簡體   English   中英

設計如何在登錄后重定向到不同的頁面(基於某些參數)?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM