我正在使用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的预期功能(需要一个特定的控制器来创建会话)所以我不想保留它。我想知道这种约束是安全措施还是只是一种约定 - 如果是为了安全,这可能是非常糟糕的。
答案 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
子类之外的身份验证,该引擎已经实现了设计身份验证。