登录或注册后设计重定向回原始位置?

Raj*_*eev 19 ruby-on-rails devise

在这里,我使用Devise Gem进行身份验证.如果有人想要在没有登录的情况下打开页面,那么它会重定向到sign_in页面,然后在登录后返回到用户尝试打开的页面.我使用Redise循环和Devise after_sign_in_path_for链接来解决我的问题,但它对我不起作用.

 def after_sign_in_path_for(resource)
   params[:next] || super 
 end
Run Code Online (Sandbox Code Playgroud)

它不会将我重定向到我要打开的页面.例如:如果我想打开"127.0.0.1:3000/post/2/edit",登录后不会返回此页面.

Bil*_*han 35

寻求的最佳资源是官方回购/维基/问题,然后是SO.你找到的答案已经过时了.

以下是答案:https://github.com/plataformatec/devise/wiki/How-To : -Redirect-back-to-current-page-after-sign-in,-sign-out,-sign-up, -update

只需在ApplicationController中为版本设计> 3.2.1添加以下内容:

    # This example assumes that you have setup devise to authenticate a class named User.
class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?
  # The callback which stores the current location must be added before you authenticate the user 
  # as `authenticate_user!` (or whatever your resource is) will halt the filter chain and redirect 
  # before the location can be stored.
  before_action :authenticate_user!

  private
    # Its important that the location is NOT stored if:
    # - The request method is not GET (non idempotent)
    # - The request is handled by a Devise controller such as Devise::SessionsController as that could cause an 
    #    infinite redirect loop.
    # - The request is an Ajax request as this can lead to very unexpected behaviour.
    def storable_location?
      request.get? && is_navigational_format? && !devise_controller? && !request.xhr? 
    end

    def store_user_location!
      # :user is the scope we are authenticating
      store_location_for(:user, request.fullpath)
    end
end
Run Code Online (Sandbox Code Playgroud)

然后在登录后重定向,您必须覆盖此方法:

def after_sign_in_path_for(resource_or_scope)
  stored_location_for(resource_or_scope) || super
end
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@Billy,它现在正在工作,这里只有一个变化是我将after_filter更改为before_filter (4认同)

Tsu*_*esu 23

您不需要所有这些代码.设计(作为最新版本)已经为您保存了位置.

只要用这个:

def after_sign_in_path_for(resource)
  request.env['omniauth.origin'] || stored_location_for(resource) || root_url
end
Run Code Online (Sandbox Code Playgroud)

这会将用户重定向到最新的omniauth.source或stored_location,最后一种情况是根URL.

我以为我被要求创建该方法,但Devise已经做到了.

资料来源:https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in


jos*_*eir 5

Devise 4开始,它为我无缝运行:

只要您使用devise的存储当前页面的位置,Devise就会在登录和注册时自动重定向 store_location_for(resource)。为此,请ApplicationController在中 编辑 app/controllers/application_controller.rb。加:

# saves the location before loading each page so we can return to the
# right page. If we're on a devise page, we don't want to store that as the
# place to return to (for example, we don't want to return to the sign in page
# after signing in), which is what the :unless prevents
before_filter :store_current_location, :unless => :devise_controller?

private
  # override the devise helper to store the current location so we can
  # redirect to it after loggin in or out. This override makes signing in
  # and signing up work automatically.
  def store_current_location
    store_location_for(:user, request.url)
  end
Run Code Online (Sandbox Code Playgroud)

将以下内容添加到中ApplicationController以使注销重定向:

private
  # override the devise method for where to go after signing out because theirs
  # always goes to the root path. Because devise uses a session variable and
  # the session is destroyed on log out, we need to use request.referrer
  # root_path is there as a backup
  def after_sign_out_path_for(resource)
    request.referrer || root_path
  end
Run Code Online (Sandbox Code Playgroud)


bis*_*hal 5

正如官方文档中所指出的,更简单的解决方案是简单地将其添加到您的application_controller.rb

class ApplicationController < ActionController::Base


private

# If your model is called User
def after_sign_in_path_for(resource)
  session["user_return_to"] || root_path
end
Run Code Online (Sandbox Code Playgroud)

重要说明(我也忽略了这一点)要使其正常工作,您需要authenticate_user!在控制器的before_action:. 这将在 Devise 中调用开箱即用的store_location_for可用,其余的由上面的代码处理,从而无需重写代码来保存请求的 url。application_controller.rb

  • 此解决方案是否适用于`remote: true` 以及不适用,而@Billy Chan 的解决方案仅适用于没有。 (2认同)