devise で未ログイン時の redirect 動作を調べて挙動を変更したい
やりたいこと
- Redirect 時に Cache-Control ヘッダを明示的に指定したい
- 未ログイン時に Redirect している箇所を調べる
- リダイレクト先は
ApplicationController
のafter_sign_out_path_for
メソッドでオーバーライド可能
- リダイレクト先は
- redirect の動作を変更したい
わかったこと
-
Devise における未ログイン時の Redirect の動作は Warden の
failure_app
の仕組みで行っている -
Devise はデフォルトの
failure_app
としてDevise::FailureApp
を用意している -
Devise の設定で
failure_app
を差し替えることができるconfig/initializers/devise.rbconfig.warden do |manager| manager.failure_app = CustomFailure end
lib/custom_failure.rbclass CustomFailure < Devise::FailureApp # redirect メソッドをオーバーライドして処理を追加する、追加した処理の後に元の redirect メソッドを呼び出す def redirect Rails.logger.debug("#### CustomFailure redirect ####") super end end
アプリケーション側で after_sign_out_path_for
をオーバーライドしているので、そのあたりを手がかりに Devise の動作を追いかけてみる。
リダイレクトしている箇所
acts_as_tenant
の set_current_tenant_through_filter
を使っていた
これはあまり関係なさそう
Devise 思い出してきた
before_action :authenticate_user!
で、未ログイン時のリダイレクトが動いていた記憶ある
Warden の authenticate!()
Devise の FailureApp
action(:respond)
は respond()
メソッドを呼び出しているっぽい
redirect
メソッド
ここをオーバーライドするとかしたら良さそう
この記事にあるように Devise::FailureApp
を拡張することでなんとかできそう
class CustomFailure < Devise::FailureApp
# redirect メソッドをオーバーライドして処理を追加する、追加した処理の後に元の redirect メソッドを呼び出す
def redirect
Rails.logger.debug("#### CustomFailure redirect ####")
super
end
end
config.warden do |manager|
manager.failure_app = CustomFailure
end
これで未ログイン時に独自の処理 Rails.logger.debug("#### CustomFailure redirect ####")
が動くことを確認した
:private
, :no_store
の他に :must_revalidate
とか追加したかったが、normalize ロジックが入ってて :no_store
のときには :private
のほかは追加されないようになっている
試しに以下のようにしてみた
class CustomFailure < Devise::FailureApp
# リダイレクトのレスポンスをキャッシュさせないようにする
def redirect
response.cache_control[:private] = true
response.cache_control[:no_store] = true
super
end
end
期待通りの Cache-Control
ヘッダになった