use*_*833 4 authentication ruby-on-rails callback devise
在我/users/sign_in登录后再次访问时,我会You are already signed in.在日志中看到闪存和以下内容.
Filter chain halted as :require_no_authentication rendered or redirected
Run Code Online (Sandbox Code Playgroud)
..我被重定向到/.我想根据某些条件调用回调和重定向.
这在精神上类似,after_sign_up_path_for除了它更像是"在登录后尝试登录".
现在,没有简单的方法来实现你想要的.(也许拉出请求是有序的.)
问题是当用户已经过身份验证时,Devise会调用该after_sign_in_path_for方法.
当用户正常登录时也会调用此方法,因此即使您重写此方法,也无法区分刚登录的用户和已登录的用户.
唯一的解决方案是扩展/覆盖Devise的SessionsController:
class SessionsController < Devise::SessionsController
private
def require_no_authentication
assert_is_devise_resource!
return unless is_navigational_format?
no_input = devise_mapping.no_input_strategies
authenticated = if no_input.present?
args = no_input.dup.push scope: resource_name
warden.authenticate?(*args)
else
warden.authenticated?(resource_name)
end
if authenticated && resource = warden.user(resource_name)
flash[:alert] = I18n.t("devise.failure.already_authenticated")
redirect_to YOUR_PATH_HERE
end
end
end
Run Code Online (Sandbox Code Playgroud)
由于此控制器继承自Devise,因此当您的控制器中未定义操作时,Devise的控制器将处理该操作.所以你只需要覆盖在before_filter中调用的require_no_authentication方法.
最后,编辑您的路线文件,以使此更改生效:
# routes.rb
devise_for :users, :controllers => { :sessions => 'sessions' }
Run Code Online (Sandbox Code Playgroud)
确保保留原始功能的最简单方法是复制整个方法定义并更改其中的部分内容。
def require_no_authentication
assert_is_devise_resource!
return unless is_navigational_format?
no_input = devise_mapping.no_input_strategies
authenticated = if no_input.present?
args = no_input.dup.push scope: resource_name
warden.authenticate?(*args)
else
warden.authenticated?(resource_name)
end
if authenticated && resource = warden.user(resource_name)
# CHANGE THE FOLLOWING LINES AS NEEDED
flash[:alert] = I18n.t("devise.failure.already_authenticated")
redirect_to after_sign_in_path_for(resource)
end
end
Run Code Online (Sandbox Code Playgroud)