设计:让多个控制器处理用户会话

时间:2011-05-26 19:12:34

标签: ruby-on-rails-3 authentication devise warden

我正在使用rails 3.0.7运行设计1.3.4。用户可以通过两种方式登录:使用网络应用,使用移动网络应用(通过JSON API调用)。第一种方法由默认设备会话控制器完美处理。 API调用的身份验证方法需要位于扩展我的Api::BaseController的控制器中。所以,我这样编写了第二个控制器:

class Api::UserSessionsController < Api::BaseController
  …
  def create
    user = warden.authenticate(:scope => :user)
    if user
      sign_in(:user, user)
    else
      # Do some error handling
    end
  end
end

由于valid_controller?中的Devise::Strategies::Authenticatable方法,尝试通过此方法登录失败。因为我已将默认控制器(devise/sessions)保留为用户的映射控制器,所以它不允许来自我的自定义控制器的身份验证。

我想将自定义功能转移到我自己的Devise::SessionsController子类中,但我需要 API会话控制器来扩展API::BaseController,所以我不能也扩展Devise::SessionsController。我不想在API控制器中放置工作的,默认行为的web-app身份验证方法,特别是因为这需要从设计控制器复制它们。

有什么建议吗?是否有一些我缺少的配置允许多个控制器处理会话? valid_controller?方法进行了==比较,而不是.include?,所以我看不出它会如何运作。

更新

这是一个糟糕的临时解决方法。我不喜欢它,所以我不是把它作为答案发布,但我认为它可能会为你所有的回答者类型提供食物思考:

在我的create方法的顶部,我可以覆盖Devise期望的会话控制器。

Devise.mappings[:user].controllers[:sessions] = params[:controller]

这正在解决Devise的预期功能(需要一个特定的控制器来创建会话)所以我不想保留它。我想知道这种约束是安全措施还是只是一种约定 - 如果是为了安全,这可能是非常糟糕的。

2 个答案:

答案 0 :(得分:1)

我只能建议另一种解决方法(可能不那么糟糕?) 在初始化程序中,您可以覆盖#valid_controller ?,如下所示:

require 'devise/strategies/authenticatable'
require 'devise/strategies/database_authenticatable'

class Devise::Strategies::DatabaseAuthenticatable
  def valid_controller?
    # your logic here
    true
  end
end

我也有兴趣了解这种约束的原因

答案 1 :(得分:0)

我正在使用Devise 2.2.7和Rails 3.2.13。上述两种方法都不适合我:valid_vontroller?中的Devise::Strategies::DatabaseAuthenticatable方法不再存在。 Devise.mappings[:user].controllers[:sessions]技巧对我来说也不起作用。

在挖掘this thread之后,我找到了valid_params_request?,它负责确保通过身份验证系统发送请求。有一个帮助方法allows_params_authentication!,它使Devise::SessionsController能够处理身份验证请求。

您可以通过以下方式从任何控制器验证用户:

def signin
  allow_params_authentication!
  authenticate_user!
end

如果要在身份验证失败时重定向到自定义页面:

resource = warden.authenticate!({
  :scope => :user,
  :recall => "#{controller_path}#login"
})
sign_in(:user, resource)

我想通过开发一个与Spree Commerce一起工作的引擎来处理Devise::SessionsController子类之外的身份验证,该引擎已经实现了设计身份验证。