如何使用rails中间件中的设计对用户进行身份验证?

时间:2016-07-01 08:48:38

标签: ruby-on-rails devise reverse-proxy rack rack-middleware

配置/ application.rb中

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

我使用rack-reverse-proxy将请求转发到另一台服务器(而不是rails服务器),当请求特定网址时,该服务器在另一台主机上运行。现在我想验证用户是否使用devise进行了signed_in,然后仅将请求转发给代理服务器,否则将用户发送回登录页面。

1 个答案:

答案 0 :(得分:3)

更新。在一般考虑中,假设目标服务器是公开可用的,您应该考虑身份验证策略,因为仅在临时服务器上检查它是不安全的。

基本上,回答你的问题是 - Devise没有为Rails应用程序添加任何自己的中间件,所以你不能在中间件中使用Devise。您可以使用Warden中间件。

Devise位于Warden之上。在中间件堆栈结束时设计injects Warden::Manager中间件(它也可以注入omniauth中间件):

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

除此之外,Devise适用于Rails应用程序级别,即添加sign_in等助手,类似于控制器。但它不适用于中间件级别本身。

Warden本身就是“懒惰”,描述为here

  

守望者是懒惰的。也就是说,如果你不使用它,它   没有做任何事情,但是当你使用它时,它会涌入   动作并提供允许身份验证的基础机制   任何基于机架的应用程序。

因此,除非Devise以某种方式与Warden一起操纵,Warden并没有做太多。 Warden所做的是embedding本身可以被其他中间件(以及Rails应用程序)访问的env变量。设计使用此实例。

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

Warden还会听取其他中间件(或最终的rails应用程序)可能抛出的特殊warden异常:

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

为了在中间件中使用Warden,您需要更早地嵌入中间件(在目标中间件之前)。然后你就可以使用Warden(而不是设计助手!)。

在warden source中的每条评论中,它应该嵌入(之前没有)会话构建中间件之后,例如ActionDispatch::Session::CookieStore

  

机架认证的中间件中间件需要   上游会话中间件注入了一个   认证对象进入机架环境哈希

守望者accessor参加会议:

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