2016-03-10 5 views
6

Ich verwende Devise 3.5 mit Omniauth in einer Rails 4 App. Ich habe eine Integration mit Facebook erstellt, die es einem Benutzer ermöglicht, seinen Facebook-Account mit meiner App zu verbinden. Wenn der Benutzer derzeit auf die Verbindungsschaltfläche klickt, werden sie an /user/auth/facebook gesendet und dann an die Rückruf-URL weitergeleitet, die Omniauth generiert: /user/auth/facebook/callback. Ich möchte diese Callback-URL in einigen Fällen manuell überschreiben - was bedeutet, dass ich sie in einem Initialisierer nicht überschreiben möchte - mit einer vollqualifizierten URL. Wenn ein Benutzer beispielsweise mit http://www.example.com/ startet, möchte ich möglicherweise die Standard-Callback-URL mit http://app.example.com/user/auth/facebook/callback überschreiben.Devise/OmniAuth Standard-Callback-URL überschreiben

Meine App hat dynamische Subdomains und ein Benutzer wird (fast) immer den Authentifizierungsprozess für eine Subdomain beginnen. Leider scheint es, dass Facebook keine Wildcards in oauth redirect URLs unterstützt, weshalb ich die Fähigkeit erkennen möchte, ob ein Benutzer in einer Subdomain ist und die Callback-URL auf etwas, das ich auf meiner Facebook-App auf die Whitelist gesetzt habe, um die Autorisierung einzustellen Prozess ist erfolgreich.

Von dem, was ich gelesen habe, akzeptiert der URL-Helper zusätzliche Argumente, die als Parameter weitergegeben werden. Ich habe versucht, in wie so einen benutzerdefinierten Callback-Weg vorbei, aber ohne Erfolg:

user_omniauth_authorize_path(:facebook, callback_path: @custom_callback) 

Ich habe auch versucht callback_path-redirect_url und redirect_uri verändern, aber nichts scheint zu funktionieren. Wenn ich den erzeugten Link ansehe, enthält er zwar den Callback als Parameter in der URL, aber wenn ich auf den Link klicke, werde ich zurück zur Standard-Callback-URL anstelle der benutzerdefinierten Callback-URL weitergeleitet.

+0

Ich brauche diese Funktion auch :( – diogopms

Antwort

0

Hier ist, wie ich dieses Problem gelöst. Ich bin sicher, es gibt andere Wege, aber dies scheint, wie die einfachste eleganteste Lösung, die ich tun konnte.

In config/routes.rb richte ich ein auth Sub-Domain auf. Alle meine Oauth Verbindungsanforderungen auf verschiedenen Sub-Domains starten und dann wird Facebook einrichten um diese Benutzer zurück an t zu senden er auth.example.com Subdomain.

constraints AuthRedirect do 
    devise_scope :contact do 
     get '/auth/facebook/callback' => 'omniauth_callbacks#facebook' 
     post '/auth/facebook/callback' => 'omniauth_callbacks#facebook' 
    end 
end 

Hier ist /lib/auth_redirect.rb. Dies überprüft nur, ob die Subdomain auth ist, und erfasst diesen Datenverkehr. Dies steht ganz oben auf meiner Routenliste, um Vorrang vor anderen Subdomains zu haben.

class AuthRedirect 
    def self.matches?(request) 
     request.subdomain.present? && request.subdomain == 'auth' 
    end 
end 

Dann in meinem Klienten, wenn ein Benutzer die Connect with Facebook Schaltfläche klickt, ich sie /auth/facebook?contact_id=<id> senden. Von hier aus leitet Devise sie zu Facebook, das sie dann zurück zu https://auth.example.com/ umleitet.

Dann in OmniauthCallbacksController#facebook kann ich die Benutzer-ID aus dem omniauth params ziehen wie so:

auth = env["omniauth.auth"] 
contact = Contact.find(env['omniauth.params']['contact_id']) 

Von hier aus kann ich die Anmeldeinformationen in die Datenbank fortbestehen und die Umleitung auf die entsprechenden Sub-Domain die Benutzer zurück. Diese Lösung vermeidet Probleme mit CSRF-Tokens und, was noch wichtiger ist, erfordert nicht die Verwendung von Ruby/ERB zum Erstellen des Omniauth-Autorisierungspfads, an den der Benutzer gesendet wird, wenn er auf die Schaltfläche zum Verbinden klickt.

1

haben Sie versucht mit redirect_uri?

user_omniauth_authorize_path(:facebook, redirect_uri: @custom_callback) 

EDIT: Entschuldigung, ich habe den zweiten Teil Ihres Beitrags verpasst.

Ich habe eigentlich das gleiche Problem in der Produktion, aber es funktioniert perfekt auf einer Staging-Umgebung. Der einzige Unterschied ist, über die Callback-URL auf Inszenierung, die eine weitere Sub-Domain hat * .staging.domain.com

Durch die Art und Weise Sie eine statische callback_url in der devise initializer Datei zur Verfügung stellen kann:

config.oaumniauth :facebook, ..., callback_url: 'url right here' 

I‘ m zu diesem Thema gestern. Entweder ich bieten eine statische URL Rückruf aber Facebook wirft mir einen CRSF Fehler:

omniauth: (facebook) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected 

Oder ich lasse die callback_url dynamisch gesetzt entwickeln, die wie

https://*.domain.com/DEVISE_MODELS/auth/facebook 

und in diesem Fall aussehen Gonna bekomme ich eine gerade Nicht übereinstimmende/Whitelist-Callback-URL während des FG-Anmeldeprozesses.

EDIT2:

GUT! Ich habe es gemacht. Ich bin in der Lage, OAUTH Login mit Wildcard-Subdomain zu bekommen.

  1. eine statische callback_url in Ihrer devise initializer Geben
  2. die Domain zu Ihrer Sitzung Speicher hinzufügen wie: domain:“.domain.com“

Mit, dass ich weder CRSF Fehler immer noch nunmatching CB url/weiße Liste gesetzt.

Hoffe, es wird für Sie arbeiten!

+0

Ich löste das tatsächlich eine Weile zurück und vergessen, meine Lösung zu posten. Es ist ganz einfach wirklich. Ich werde meine Antwort mit der Lösung aktualisieren, die ich verwendet habe. Leider habe ich nicht die Zeit oder Ressourcen, um Ihre Lösung derzeit zu testen, aber es sieht lebensfähig, so werde ich es eine Verbesserung geben. – ACIDSTEALTH