Rails:登录或注册后设计重定向到存储位置?
Posted
技术标签:
【中文标题】Rails:登录或注册后设计重定向到存储位置?【英文标题】:Rails: Devise redirect to a stored location after sign in or sign up? 【发布时间】:2011-07-12 10:25:51 【问题描述】:我正在编写的 Rails 应用程序中使用 Devise,我想让用户在登录或注册后回到他们所在的位置。
例如,如果我有一个受以下保护的“cmets”控制器:
before_filter :authenticate_user!
然后我希望用户点击“立即评论!”按钮(并因此重定向到 CommentsController 中的新操作)登录,然后让 Devise 将它们重定向到 CommentsController 中的新操作(或它们所在的任何位置),而不是应用程序的通用根目录或通用 after_sign_in_path。
查看 Devise 的 RDOC,我发现 this method 看起来好像 Devise 至少有 capability 自己做这样的事情,但我不知道一种方式。
【问题讨论】:
【参考方案1】:我认为默认情况下 Devise 会保存路线,但您可能正在使用
sign_in @user
这应该会重定向你
sign_in_and_redirect(@user) #assuming you are sigining in that resource
【讨论】:
使用before filter :sign_in_and_redirect(@user)
不起作用。给出的错误表明无法传递参数。 (即“意外字符'('”)如何使用此代码获得 before_filter 的等效行为?
我一直在搞乱它,这就是我想出的。首先,设计存储您在redirect_location_for(:user)
中点击的第一个URL,假设“用户”是您的模型。其次,如果您将redirect_to redirect_location_for(:user)
添加到您的签名控制器中,这一切都应该像魔术一样工作【参考方案2】:
好的,所以我做了更多的实验,并使用 Kormie 的信息,我得到了一个可行的解决方案。
据我所知,before_filter authenticate_user!
确实不保存返回用户的路线。我所做的是:
首先,我在控制器顶部添加了一个额外的before_filter
before_filter :store_location
before_filter :authenticate_user!
然后,我在控制器底部写了store_location
方法
private
def store_location
session[:user_return_to] = any_old_route_path
end
我并不认为这是完美的,但它对我有用。 (对于其他想要使用它的人来说,它的缺点是每个控制器只支持一个返回路径。这就是我自己所需要的,但与我之前使用的每个应用程序一个返回路径相比,它只是略有改进。 ) 我真的很感谢其他人的见解和建议。
【讨论】:
我有一些看起来像这样的代码:session[:login_redirect] = request.path unless current_user
请注意,我没有使用:user_return_to
,因为它已经在内部用于设计 facebook 连接回调。所以改为我自己的变量+签入自定义after_sign_in_path_for
【参考方案3】:
你试过after_sign_in_path_for吗?如果您在 ApplicationController 中定义该方法,它应该覆盖每个控制器的默认实现。
【讨论】:
【参考方案4】:Devise 应该自己做这件事。身份验证用户!当通过 PUT 方法设置操作的路由时,过滤器也不想为我工作。当我在 routes.rb 中将此更改为 GET 时,设计开始按预期工作。
【讨论】:
【参考方案5】:简单的方法:
# Modified from https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
stored_location_for(resource) || your_defaut_path
end
end
【讨论】:
【参考方案6】:改编自 Devise Wiki 如何:
登录、退出、注册、更新后重定向回当前页面
重定向回“当前页面”涉及将当前 url 保存在会话中,然后在用户通过身份验证/退出后从会话中检索 url。这应该只对 GET 请求真正执行,因为其他 http 方法(POST、PUT、PATCH、DELETE)不是幂等的,不应自动重复。
要为整个应用程序存储位置,请使用 before_action 设置回调(在 4.0 之前的 Rails 版本中使用 before_filter)。
此示例假定您已设置设计来验证名为 User 的类。
# app/controllers/application_controller.rb
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!
# To redirect to the stored location after the user signs
# signs in you would override the after_sign_in_path_for method:
def after_sign_in_path_for(resource_or_scope)
# *My note, not wiki*: you may need a fall back as
# stored_location_for can return nil. I've added root_path
stored_location_for(resource_or_scope) || root_path
end
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
参考
Devise How To: Redirect back to current page after sign in, sign out, sign up, update
【讨论】:
以上是关于Rails:登录或注册后设计重定向到存储位置?的主要内容,如果未能解决你的问题,请参考以下文章