在安装的引擎中设计使用错误的 url 作为 401
Devise in a mounted engine uses wrong url for a 401
我在 Rails 应用程序 (my_application
) 的已安装引擎 (my_engine
) 中使用 Devise。这工作得很好,但仍然存在一个问题:如果用户试图访问受限资源(即受 before_filter authenticate_user!
保护的页面)Devise/Warden 生成 401 响应并重定向到 sign_in url。不幸的是,这个 sign_in url 没有以引擎的安装路径为前缀。
所以我的问题是 Devise 用于将浏览器转发到 sign_in 页面的 url 是错误的。
引擎的 routes.rb
文件是...
My_Engine::Engine.routes.draw do
devise_for :users, {
class_name: "My_Engine::User",
module: :devise,
controllers: {registrations: 'my_engine/users/registrations'}
}
devise_scope :user do
get 'users/registrations/after_sign_up/:id' => "users/registrations#after_sign_up", as: :after_sign_up
get 'users/registrations/after_confirm/:id' => "users/registrations#after_confirm", as: :after_confirm
end
end
生成的路由都ok:
Prefix Verb URI Pattern Controller#Action
my_engine /my_engine My_Engine::Engine
Routes for My_Engine::Engine:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) my_engine/users/registrations#cancel
user_registration POST /users(.:format) my_engine/users/registrations#create
new_user_registration GET /users/sign_up(.:format) my_engine/users/registrations#new
edit_user_registration GET /users/edit(.:format) my_engine/users/registrations#edit
PATCH /users(.:format) my_engine/users/registrations#update
PUT /users(.:format) my_engine/users/registrations#update
DELETE /users(.:format) my_engine/users/registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
after_sign_up GET /users/registrations/after_sign_up/:id(.:format) my_engine/users/registrations#after_sign_up
after_confirm GET /users/registrations/after_confirm/:id(.:format) my_engine/users/registrations#after_confirm
现在,当我访问受保护的资源时,Devise 会生成 401 并重定向到 sign_in 路径,但 url 没有前缀为“/my_engine”。
它使用/users/sign_in
,但应该使用/my_engine/users/sign_in
。
19:41:11 web.1 | Started GET "/my_engine/users/edit" for ::1 at 2015-03-09 19:41:11 +0100
19:41:11 web.1 | Processing by My_Engine::Users::RegistrationsController#edit as HTML
19:41:11 web.1 | Completed 401 Unauthorized in 1ms
19:41:11 web.1 |
19:41:11 web.1 |
19:41:11 web.1 | Started GET "/users/sign_in" for ::1 at 2015-03-09 19:41:11 +0100
19:41:11 web.1 |
19:41:11 web.1 | ActionController::RoutingError (No route matches [GET] "/users/sign_in"):
19:41:11 web.1 | actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
有没有人遇到过这个?似乎引擎中的 omniauthenticable 存在相关问题,但我不确定它们是否具有相同的原因。
看看Ativ的回答,解决了我的问题。
简而言之,我不得不在引擎的lib文件夹中添加一个Devise::FailureApp,告诉Devise使用它并在启动时加载它。
详情见github。
我在 Rails 应用程序 (my_application
) 的已安装引擎 (my_engine
) 中使用 Devise。这工作得很好,但仍然存在一个问题:如果用户试图访问受限资源(即受 before_filter authenticate_user!
保护的页面)Devise/Warden 生成 401 响应并重定向到 sign_in url。不幸的是,这个 sign_in url 没有以引擎的安装路径为前缀。
所以我的问题是 Devise 用于将浏览器转发到 sign_in 页面的 url 是错误的。
引擎的 routes.rb
文件是...
My_Engine::Engine.routes.draw do
devise_for :users, {
class_name: "My_Engine::User",
module: :devise,
controllers: {registrations: 'my_engine/users/registrations'}
}
devise_scope :user do
get 'users/registrations/after_sign_up/:id' => "users/registrations#after_sign_up", as: :after_sign_up
get 'users/registrations/after_confirm/:id' => "users/registrations#after_confirm", as: :after_confirm
end
end
生成的路由都ok:
Prefix Verb URI Pattern Controller#Action
my_engine /my_engine My_Engine::Engine
Routes for My_Engine::Engine:
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) my_engine/users/registrations#cancel
user_registration POST /users(.:format) my_engine/users/registrations#create
new_user_registration GET /users/sign_up(.:format) my_engine/users/registrations#new
edit_user_registration GET /users/edit(.:format) my_engine/users/registrations#edit
PATCH /users(.:format) my_engine/users/registrations#update
PUT /users(.:format) my_engine/users/registrations#update
DELETE /users(.:format) my_engine/users/registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
after_sign_up GET /users/registrations/after_sign_up/:id(.:format) my_engine/users/registrations#after_sign_up
after_confirm GET /users/registrations/after_confirm/:id(.:format) my_engine/users/registrations#after_confirm
现在,当我访问受保护的资源时,Devise 会生成 401 并重定向到 sign_in 路径,但 url 没有前缀为“/my_engine”。
它使用/users/sign_in
,但应该使用/my_engine/users/sign_in
。
19:41:11 web.1 | Started GET "/my_engine/users/edit" for ::1 at 2015-03-09 19:41:11 +0100
19:41:11 web.1 | Processing by My_Engine::Users::RegistrationsController#edit as HTML
19:41:11 web.1 | Completed 401 Unauthorized in 1ms
19:41:11 web.1 |
19:41:11 web.1 |
19:41:11 web.1 | Started GET "/users/sign_in" for ::1 at 2015-03-09 19:41:11 +0100
19:41:11 web.1 |
19:41:11 web.1 | ActionController::RoutingError (No route matches [GET] "/users/sign_in"):
19:41:11 web.1 | actionpack (4.2.0) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
有没有人遇到过这个?似乎引擎中的 omniauthenticable 存在相关问题,但我不确定它们是否具有相同的原因。
看看Ativ的回答,解决了我的问题。
简而言之,我不得不在引擎的lib文件夹中添加一个Devise::FailureApp,告诉Devise使用它并在启动时加载它。
详情见github。