![](/img/trans.png)
[英]Devise how to redirect to different page (based on some parameter) after sign out?
[英]Devise how to redirect to different page (based on some parameter) after sign in?
在我的應用程序中,我有兩個來自兩個控制器的不同登錄表單,它們都將通過 Devise::SessionsController 登錄,問題是在成功登錄(或失敗)后,我需要重定向到特定於控制器的不同頁面。 我怎樣才能做到這一點。 我目前在我的 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
在應用程序控制器中
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
如果有人仍在尋找解決方法。 我能夠通過以下方式解決這個問題:
首先,創建一個繼承自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
你會注意到我正在設置一個類變量( @@variable_name
),我並不熱衷於此,但這是我在嘗試各種其他方法來解決這個問題 4 小時后想出的。 我也盡量小心不要過多地使用 Devise 的控制器,不要使用super
並且只包括我關心的動作。
接下來,在路由中,您現在可以將設計的默認值指向上面的控制器。 對於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
它可能不是 DRYest 解決方案,但它是我能夠想出的唯一一個將重定向指向原始頁面而不是 root 或無限循環的解決方案。
您可以通過在控制器中定義after_sign_in_path_for
方法來完成此操作,您可以在其中自定義此重定向路徑。
以下是更全局的解決方案,但可以在您的情況下使用。 它使用 attr_accessor。 after_sign_in_path_for
操作不需要額外的參數,也不需要類變量。
class User < ActiveRecord::Base
attr_accessor :redirect_to
end
然后,使用專用的 session_controller 文件(按照 Devise 的建議覆蓋),復制粘貼原始設計操作並在 respond_with 之前添加行resource.redirect_to = sign_in_params[:redirect_to]
。 將新重定向添加到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
最后,更新您的視圖以設置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
會將您的用戶重定向到www.test.com
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.