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
ヘッダになった