web-dev-qa-db-ja.com

ログイン失敗後のリダイレクトの考案

私が見つけたすべての質問は、ヘルパーafter_sign_in_path_for(resource)を使用したログインの成功に関連しています

サイトのインデックスにログインフォームがあり、ログインに失敗すると「users/sign_in」にリダイレクトされます

しかし、ログインが失敗したときに「site#index」にリダイレクトするにはどうすればよいですか?

54
Juanjo
  1. Libディレクトリにcustom_failure.rbを作成します:

    class CustomFailure < Devise::FailureApp
      def redirect_url
        your_path
      end
    
      def respond
        if http_auth?
          http_auth
        else
          redirect
        end
      end
    end
    
  2. Deviseイニシャライザーに以下を含めます。

      config.warden do |manager|
        manager.failure_app = CustomFailure
      end
    
  3. 必ずRailsがapplication.rbのlibファイルに読み込まれます:

    config.autoload_paths += %W(#{config.root}/lib)
    

サーバーを再起動することを忘れないでください。

これを行う簡単な方法はないと思います。幸運を。

93
Marco Antonio

独自のSessionsControllerを使用する場合、warden.authenticate!(auth_options)を実行する前に、_:recall_の_auth_options_値を再割り当てして、必要な_controller#method_を呼び出すことができます。例えば:

app/controllers/users/sessions_controller.rb

_class Users::SessionsController < Devise::SessionsController
  #...
  def create
    #...
    auth_options = { :recall => 'site#index', :scope => :user }
    resource = warden.authenticate!(auth_options)
    #...
  end
  #...
end
_

この方法を使用すると、カスタマイズされたFailureAppを作成して構成を変更する必要はありません。

14
Sibevin Wang

これがdevise 3.1.0で起こることです

Started POST "/users/sign_in"
Processing by Devise::SessionsController#create
Completed 401 Unauthorized
Processing by Devise::SessionsController#new

gems/devise-3.1.0/app/controllers/devise/sessions_controller.rbの最後に定義されているauth_optionsのために、新しいが呼び出されます

Createアクションで使用されるauth_optionsを再定義する必要があります。 Railsアプリケーションのapp/controllers/devise/sessions_controller.rbにコントローラーをコピーし、auth_optionsメソッドをこのように置き換えました

def auth_options
  { :scope => resource_name, :recall => "Home#new" }
end

それはトリックを行いますが、URLはまだ/ users/sign_inです

私もそれを修正しようとします。

3
pmontrasio

デフォルトのsign_inパスを変更できます。

チェックアウト https://github.com/plataformatec/devise/wiki/How-To:-Change-the-default-sign_in-and-sign_out-routes

1
MikeH

Marcaoの答えを詳しく説明すると、何が起こっているかをよりよく理解するために、CustomFailure応答メソッドに debugger を配置することを強くお勧めします。

_Class CustomFailure < Devise::FailureApp
  def respond
    binding.pry
    super
  end
end
_

Respondメソッドの FailureApp Devise Source Code を見ると、何が起こっているのかを非常に簡単に理解できます。

_def respond
  if http_auth?
    http_auth
  elsif warden_options[:recall]
    recall
  else
    redirect
  end
end
_

たとえば、redirect_urlを返すには、respondコード条件が最終的にredirectを返すようにする必要があります。

ただし、 http_auth メソッドで定義されている標準の401ステータスを返したい場合は、respondメソッドコードが_http_auth_を返すことを確認する必要があります。

したがって、_http_auth?_の定義を調べることは価値があります。特に、json要求に対して0を返す_request.xhr?_メソッドに注意してください(Rubyでは0は実際にtrueと評価されることを思い出してください)

_def http_auth?
  if request.xhr?
    Devise.http_authenticatable_on_xhr
  else
    !(request_format && is_navigational_format?)
  end
end
_

また、必要な応答を制御するために、_config.http_authenticatable_on_xhr_または_config.navigational_formats_のinitializers/deviseファイルを確認してください。この構成は、Deviseが返す内容に実際に影響を与える可能性があり、多くの場合、内部で行われることにより予期しない動作を引き起こす可能性があります。

0
AmitF