使用 devise login 作为 root 在无限循环中调用单独的 root 并导致“url 重定向你太多次”

Using devise login as root calls separate root in an infinite loop and causes " url redirected you too many times"

用户登录后,关闭页面并重新打开页面被重定向了太多次。 rails 终端显示以下两条路由相互无限调用,但我不明白为什么会这样。任何帮助将不胜感激。

Started GET "/users/sign_in" for xxx.xxx.xxx.xx at 2019-07-20 20:52:11
Started GET "/" for xxx.xxx.xxx.xx at 2019-07-20 20:52:12

从 devise 登录更改 root 可以解决问题,但这不是我们想要的。

routes.rb

Rails.application.routes.draw do
  devise_for :users, controllers: {sessions: "sessions"}
  root :to => redirect("/users/sign_in")
  post 'pindex', to: 'locker#index'
  get 'view',   to: 'locker#view'
  post 'view', to: 'locker#many_new'
  match 'sort/:type', to: 'locker#sort', :via => :get, :as => :sort
  resources :locker
 end

sessions_controller.rb

 class SessionsController < Devise::SessionsController
  def new
    super
  end

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    if !session[:return_to].blank?
     redirect_to session[:return_to]
      session[:return_to] = nil
    else
      respond_with resource, :location => locker_index_path
     end
   end
 end

new.html.erb

 <%= form_for(resource, as: resource_name, url: 
 session_path(resource_name)) do |f| %>
    </span>
     <%= f.email_field :email,
     class: "form-control", 
     placeholder: "Email Address",
     required:"required"%>  
    </span>
    <%= f.password_field :password, 
      class: 'form-control',
      placeholder: "Password",
      required:"required"%> 
     <%= f.submit "Log In", class: "btn btn-primary btn-block btn-lg"%>
 <%end%>

查看 Devise 的源代码,您可以看到在 SessionsController 中他们在 new.

之前调用了 require_no_authentication
prepend_before_action :require_no_authentication, only: [:new, :create]

如果用户已登录,此方法将重定向到 after_sign_in_path_for(resource)。默认情况下 after_sign_in_pathroot_path,您将其重定向到 sessions#new。所以这是你的无限循环。

if authenticated && resource = warden.user(resource_name)
  flash[:alert] = I18n.t("devise.failure.already_authenticated")
  redirect_to after_sign_in_path_for(resource)
end

要解决它,您应该用 root_path 以外的其他内容覆盖 SessionsController 中的 after_sign_in_path_for

def after_sign_in_path_for(_resource_or_scope)
  locker_index_path # or anything you want
end