[英]Devise how to redirect to different page (based on some parameter) after sign in?
In my application, I have two different login forms from two controller which will both sign_in through the Devise::SessionsController, the problem is after successful sign in (or failure) I need to redirect to different pages that specific to the controller.在我的应用程序中,我有两个来自两个控制器的不同登录表单,它们都将通过 Devise::SessionsController 登录,问题是在成功登录(或失败)后,我需要重定向到特定于控制器的不同页面。 How can I do this.
我怎样才能做到这一点。 I currently have this in my Devise::SessionsController, which
我目前在我的 Devise::SessionsController 中有这个
class SessionsController < Devise::SessionsController
def create
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
return sign_in_and_redirect(resource_name, resource)
end
def sign_in_and_redirect(resource_or_scope, resource=nil)
scope = Devise::Mapping.find_scope!(resource_or_scope)
resource ||= resource_or_scope
sign_in(scope, resource) unless warden.user(scope) == resource
redirect_to dashboard_path
end
def failure
redirect_to index_path
end
end
In application controller在应用程序控制器中
before_filter :store_location
def store_location
unless params[:controller] == "devise/sessions"
url = #calculate the url here based on a params[:token] which you passed in
session[:user_return_to] = url
end
end
def stored_location_for(resource_or_scope)
session[:user_return_to] || super
end
def after_sign_in_path_for(resource)
stored_location_for(resource) || root_path
end
If anyone is still looking for a work around.如果有人仍在寻找解决方法。 I was able to solve this by:
我能够通过以下方式解决这个问题:
First, create a Sessions controller inheriting from Devise::SessionsController
首先,创建一个继承自
Devise::SessionsController
的 Sessions 控制器
class SessionsController < Devise::SessionsController
def new
get_pre_login_url(request.referer)
super
end
def create
@@referer_url
super
end
private
def get_pre_login_url(url)
@@referer_url = url
end
def after_sign_in_path_for(resource)
# @@referer_url
sign_in_url = url_for(:action => 'new', :controller => 'sessions', :only_path => false, :protocol => 'http')
if @@referer_url == sign_in_url
super
else
stored_location_for(resource) || @@referer_url || root_path
end
end
end
You'll notice I'm setting a class variable ( @@variable_name
), which I'm not keen on, but this is what I came up with after 4 hours of trying various other ways of solving this.你会注意到我正在设置一个类变量(
@@variable_name
),我并不热衷于此,但这是我在尝试各种其他方法来解决这个问题 4 小时后想出的。 I'm also trying to be careful not to screw with Devise's controller too much and using super
and only including the actions I care about.我也尽量小心不要过多地使用 Devise 的控制器,不要使用
super
并且只包括我关心的动作。
Next, in routes you can now point Devise's defaults to the Controller above.接下来,在路由中,您现在可以将设计的默认值指向上面的控制器。 You don't need it exactly like below for the
devise_for
, just the part referencing the controllers: { sessions: "sessions" }
对于
devise_for
,您不需要完全像下面devise_for
,只需要引用controllers: { sessions: "sessions" }
的部分controllers: { sessions: "sessions" }
MyPortfolio::Application.routes.draw do
devise_for :users, path_names: { sign_in: "login",
sign_out: "logout" },
controllers: { omniauth_callbacks: "omniauth_callbacks",
sessions: "sessions" }
resources :posts do
resources :comments
end
resources :projects do
resources :comments
end
resources :users
root :to => 'home#index'
get 'login' => 'devise/sessions#new'
get 'about_me' => 'about#index'
end
It might not be the DRYest solution around, but it was the only one that I was able to come up with to point the redirect back to the page of origin instead of root or an infinite loop.它可能不是 DRYest 解决方案,但它是我能够想出的唯一一个将重定向指向原始页面而不是 root 或无限循环的解决方案。
您可以通过在控制器中定义after_sign_in_path_for
方法来完成此操作,您可以在其中自定义此重定向路径。
The following is more global solution but it can be used in your case.以下是更全局的解决方案,但可以在您的情况下使用。 It uses attr_accessor.
它使用 attr_accessor。 No extra params to
after_sign_in_path_for
action and no class variable required. after_sign_in_path_for
操作不需要额外的参数,也不需要类变量。
class User < ActiveRecord::Base
attr_accessor :redirect_to
end
Then, with a dedicated sessions_controller file (override as recommended by Devise), copy-paste the original devise action and add the line resource.redirect_to = sign_in_params[:redirect_to]
before respond_with.然后,使用专用的 session_controller 文件(按照 Devise 的建议覆盖),复制粘贴原始设计操作并在 respond_with 之前添加行
resource.redirect_to = sign_in_params[:redirect_to]
。 Add the new redirect to the after_sign_in_path_for
action and add the :redirect_to
params to devise allowed signin params.将新重定向添加到
after_sign_in_path_for
操作并添加:redirect_to
参数以设计允许的登录参数。
# app/controllers/devise/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
before_filter :configure_sign_in_params, only: [:create]
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message!(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
# set redirect_to
resource.redirect_to = sign_in_params[:redirect_to]
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
# set url to redirect_to url if present
def after_sign_in_path_for(resource_or_scope)
return resource_or_scope.redirect_to if resource_or_scope.redirect_to.present? && !resource_or_scope.respond_to?(:devise_scope)
stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
end
# add redirect_to to devise signin allowed params
def configure_sign_in_params
devise_parameter_sanitizer.for(:sign_in) << :redirect_to
end
end
Finally, update your view to set a hidden param for the redirect_to
url最后,更新您的视图以设置
redirect_to
url 的隐藏参数
# app/views/users/sessions/new.html.haml
# from params in url
<% if (param_redirect_to = params[:redirect_to]).present?
<%= f.hidden_field :redirect_to, value: param_redirect_to %>
<% end %>
# or hardcoded if you have 2 sign-in forms
<%= f.hidden_field :redirect_to, value: 'your custom redirect url' %>
GET http://localhost:3000/login?redirect_to=www.test.com
will redirect your user to www.test.com after successful signing成功签名后,
GET http://localhost:3000/login?redirect_to=www.test.com
会将您的用户重定向到www.test.com
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.