2017-02-01 3 views
1

Hier ist die Situation. Ich habe eine Multi-Tenant Rails App, die das Apartment Juwel nutzt, wo ich eine LinkedIn OmniAuth Strategie implementieren muss.OmniAuth mit einer Multi-Tenant Rails 5 App entwickeln

Wie Sie auf meinen Routen sehen können, bleiben die Benutzer von Devise und die zugehörigen Routen nur für die einzelnen Schemas der Subdomänen erhalten.

Beispiel Route:

Gute: https://frank.example.io/users/sign_in

Bad: https://example.io/users/sign_in

Routen

class SubdomainPresent 
    def self.matches?(request) 
    request.subdomain.present? 
    end 
end 

class SubdomainBlank 
    def self.matches?(request) 
    request.subdomain.blank? 
    end 
end 

Rails.application.routes.draw do 
    constraints(SubdomainPresent) do 

    ... 

    devise_for :users, controllers: { 
     omniauth_callbacks: 'omniauth_callbacks' 
    } 
    devise_scope :user do 
     get '/users/:id', to: 'users/registrations#show', as: "show_user" 
    end 

    ... 

    end 
end 

Mein spezifisches Problem ist, dass LinkedIn Platzhalter mit ihrem Rückruf nicht unterstützt U RLs, so dass ich nicht weiß, wie ich Benutzer nach der OAuth-Authentifizierung in die richtige Domäne leiten kann.

+0

Sie müssten eine Controlleraktion hinzufügen, mit der Sie den Benutzer auf die entsprechende Benutzerseite umleiten. Ich schätze, die LinkedIn API gibt eine Art 'user_id' zurück? Hier müssen Sie anfangen. – CottonEyeJoe

+0

Leider wegen der Schemas, die möglicherweise nicht möglich sind. Wenn ich Schemata 'A' und' B' hätte, könnte jeder einen Benutzer mit 'user.id == 1' haben. – Will

Antwort

1

So stellt sich heraus die Antwort war Parameter in der Genehmigung Link zu passieren, die schließlich an die Callback Aktion Throught request.env["omniauth.params"]

Authorization Link-Format übergeben bekommen würde:

Hier wurde ich Probleme, das Hinzufügen der Parameter zum Devise URL Builder, also habe ich die Parameter nur manuell hinzugefügt. Dies ist vermutlich auf einen URL Helfer

<%= link_to "Connect your Linkedin", "#{omniauth_authorize_path(:user, :linkedin)}?subdomain=#{request.subdomain}" %> 

Routen verschoben werden:

Dann definierte ich eine Route durch eine leere Sub-Domain beschränkt deutet auf die Callback-Aktion.

class SubdomainPresent 
    def self.matches?(request) 
    request.subdomain.present? 
    end 
end 

class SubdomainBlank 
    def self.matches?(request) 
    request.subdomain.blank? 
    end 
end 

Rails.application.routes.draw do 
    constraints(SubdomainPresent) do 
    ... 
    devise_for :users, controllers: { 
     omniauth_callbacks: 'omniauth_callbacks' 
    } 
    resources :users 
    ... 
    end 

    constraints(SubdomainBlank) do 
    root 'welcome#index' 
    ... 
    devise_scope :user do 
     get 'linkedin/auth/callback', to: 'omniauth_callbacks#linkedin' 
    end 
    ... 
    end 
end 

Controller:

benutzte ich dieses Tutorial meine Callback-Controller einzurichten: Rails 4 OmniAuth using Devise with Twitter, Facebook and Linkedin. Mein Hauptziel mit dem Callback-Controller war es in der leeren Subdomain zu bleiben, so dass ich nur eine Rückruf-URL zu meiner LinkedIn Dev App geben musste. Mit diesem Controller suche ich die omniauth-Parameter für den Subdomain-Parameter und verwende diese, um zum richtigen Schema zu wechseln.

def self.provides_callback_for(provider) 
    class_eval %Q{ 
    def #{provider} 
     raise ArgumentError, "you need a subdomain parameter with this route" if request.env["omniauth.params"].empty? 

     subdomain = request.env["omniauth.params"]["subdomain"] 
     Apartment::Tenant.switch!(subdomain) 
     ... 
    end 
    } 
end 
0

könnten Sie jede Domäne als Callback mit verknüpft registrieren (ich denke, wenn Sie eine Menge haben, die nicht schnell verwaltet werden kann) .. Sie könnten den Benutzer cookie bevor Sie sie an linkedin senden, so dass Sie wissen, zu welcher Subdomain sie gehören .

+0

Leider werden Subdomains dynamisch generiert. Aber die Cookie-Idee ist interessant, das könnte nützlich sein. – Will