2016-07-01 26 views
2

config/application.rbWie authentifiziert man Benutzer mit Hilfe von Rails Middleware?

config.middleware.insert_before(Rack::Runtime, Rack::ReverseProxy) do 
    reverse_proxy_options preserve_host: false 
    reverse_proxy '/external/app', 'https://runalong.com:64167/app' 
end 

Ich bin mit Rack-Reverse-Proxy weiterleiten Anforderungen an einem anderen Server (nicht Schienen-Server), die in einem anderen Host ausgeführt wird, wenn eine bestimmte URL angefordert wird. Jetzt möchte ich überprüfen, ob der Benutzer signed_in mit dem Gerät ist und dann nur die Anfragen an den Proxy-Server weiterleiten, andernfalls den Benutzer zurück zur Anmeldeseite senden.

+0

Fügen Sie Details zur Konfiguration von Devise (und dem zugrunde liegenden Warden) für Ihre App hinzu. Standardmäßig wird Warden :: Manager Middleware am [Ende] (https://github.com/plataformatec/devise/blob/e01fdba557f0da3c9a528011edee5b4e0989722d/lib/devise/rails.rb#L8) des Middlewares-Stacks hinzugefügt, wesentlich später als Rack: :Laufzeit. Daher wird es in deinem Code noch nicht verfügbar sein –

Antwort

2

Aktualisierung. Unter der Annahme, dass der Zielserver öffentlich verfügbar ist, sollten Sie eine Authentifizierungsstrategie in Betracht ziehen, da eine Überprüfung nur auf Ihrem Interimserver nicht sicher ist.

Im Grunde wird die Antwort auf Ihre Frage sein - Devise fügt der Rails-Anwendung keine eigene Middleware hinzu, so dass Sie Devise nicht in Middleware verwenden können. Sie können Warden Middleware möglicherweise verwenden.

Devise sitzt auf Warden. Ersinnen injectsWarden::Manager Middleware am Ende der Middleware-Stapel (es kann auch omniauth Middle injizieren):

# Initialize Warden and copy its configurations. 
config.app_middleware.use Warden::Manager do |config| 
    Devise.warden_config = config 
end 

Andere dann, dass, Devise arbeitet auf Rails Anwendungsebene, das heißt hinzuzufügen Helfer wie sign_in und ähnliche Steuerungen. Aber es funktioniert nicht auf Middleware-Ebene selbst.

Warden selbst ist "lazy", die here

Warden ausgelegt ist beschrieben faul. Das heißt, wenn Sie es nicht verwenden, tut es nichts tun, aber wenn Sie es verwenden, wird es in Aktion springen und bieten einen zugrunde liegenden Mechanismus zur Authentifizierung in beliebige Rack-basierte Anwendung zu ermöglichen.

Also, wenn Devise nicht irgendwie mit Warden manipuliert, tut Warden nicht viel. Was Warden macht, ist embedding selbst in env-Variable, auf die andere Middleware (und auch Rails-Anwendungen) zugreifen können. Verwenden Sie diese Instanz.

env['warden'] = Proxy.new(env, self) 

Warden hört auch auf spezielle warden Ausnahmen, die andere Middle (oder in der Anwendung Endschiene) werfen können:

result = catch(:warden) do 
    @app.call(env) 
end 

Um Warden zu verwenden, in Middleware, würden Sie in Middleware einbinden müssen früher (vor Ihrer Ziel-Middleware). Dann könntest du Warden benutzen (und nicht Devise-Helfer!).

Pro Kommentare in Warden source, sollte es nach (nicht früher) Sitzung-Building Middleware, z.ActionDispatch::Session::CookieStore:

Die Middleware für Rack-Authentication Die Middleware , dass es eine Sitzung vorgeschalteten Die Middleware spritzt eine Authentifikationsobjekt in die Rackumgebung hash

Warden accessor für Sitzung erfordert:

def session 
    env["rack.session"] || {} 
end