我在我的Rails 4.2.6应用程序中使用了Devise 3.5.6和一个StaffUser
类,很长一段时间没有问题。该应用可通过staff.example.com
访问。
现在我已经创建了第二个ClientUser
课程,以便通过client.example.com
访问该应用的单独部分。
两个用户类都有自己的作用域视图和扩展会话控制器(在ClientUser
的情况下,这仅仅是为了覆盖使用的布局)。
我遇到的问题是登录的ClientUser
通常会在受保护的网页成功加载之前多次循环/重定向以下步骤:
/foo
,回复是401 Unauthorized /client_users/session/new
/foo
这种情况发生在生产中的大多数请求中,但很少在开发中。
它会多次运行此循环(在浏览器中触发Chrome的“Too many redirects”警告),然后停在最初请求的页面上。用户在任何时候都没有机会再次登录,因此他们必须首先获得授权。
这似乎不会影响StaffUser
。
配置/ routes.rb中
constraints subdomain: 'client' do
devise_for :client_users, controllers: {
sessions: 'devise/client_sessions'
}
resources :client_app_object
end
constraints subdomain: 'staff' do
devise_for :staff_users, controllers: {
sessions: 'devise/staff_sessions'
}
resources :staff_app_object
end
配置/初始化/ devise.rb
config.scoped_views = true
config.default_scope = :staff_user
config.warden do |manager|
manager.failure_app = CustomFailure
end
LIB /色器件/ custom_failure.rb
class CustomFailure < Devise::FailureApp
def redirect_url
if request.subdomain == 'staff'
new_staff_user_session_url(subdomain: request.subdomain)
elsif request.subdomain == 'client'
new_client_user_session_url(subdomain: request.subdomain)
else
# incorrect/missing subdomain
raise CustomFailureException
end
end
...
end
我的工作理论是,Devise正在尝试从会话中检索ClientUser
,但是将其视为StaffUser
,从而导致最初的401 Unauthorized。
这里会出现竞争条件吗?
设计如何知道要实例化哪个用户类?
由于
编辑1 - config / initializers / session_store.rb
Rails.application.config.session_store :cookie_store, key: '_my_session'
答案 0 :(得分:0)
我发现我的问题的原因是我将默认的Devise控制器(和我的应用程序控制器)扩展到与模型的类名冲突的命名空间。具体为Client::*****Controller
vs Client
。
将类名称空间更改为未使用的名称可解决冲突。
同样的问题还有其他副作用使问题混乱。这些包括扩展类中的before_action
过滤器没有触发,可能是因为它们没有被正确扩展 - 尽管我还不知道为什么这种情况是静默地发生而且只是间歇性地发生。