Deviceを使って認証機能を作った場合、通常ではログイン済みのユーザーはパスワードリセットのページには飛べません。つまり「パスワードを忘れた時」などのページに飛ぼうとするとログイン後に遷移するページに飛ばされてしまいます。
ログイン済みのユーザーでも「パスワードを忘れた時」のページに飛んでパスワードをリセットできる様にします。
結論
skip_before_action :require_no_authentication, only: :new, if: :user_signed_in?
protected
def after_resetting_password_path_for(resource)
bypass_sign_in(resource) if user_signed_in?
your_signed_in_path
end
結論としては、PasswordsController
に上記の設定を追加してあげればPassowrds#newに遷移することができます。
require_no_authentication
require_no_authentication
とは、特定のアクションやコントローラー内で、ユーザーがログインしていないことを要求するために使用するメソッドです。これを skip_before_action
でスキップしてあげることで条件が解除されます。
つまり前述のコードでは以下の様な意味になります
skip_before_action :require_no_authentication, only: :new, if: :user_signed_in?
# もしユーザーがログインしていたらnewのみログインしていないことを条件とするメソッドをスキップする
リセット後にログイン後のページに遷移する
前述までの処理で、ログイン済みのユーザーでもパスワードリセットのページにアクセスできる様になりました。しかしログイン状態でパスワードを再設定すると自動的にログアウト状態になってしまい、通常の遷移処理ではログイン後のページに飛べなくなってしまうのでその対策を行います。
リセット後に任意のページに遷移する
まずは通常の遷移設定ですが、以下のafter_resetting_password_path_for
を ApplicationController
や PasswordsController
などで上書きすることで、パスワードリセット後に任意のページに遷移させることができます。
def after_resetting_password_path_for(resource)
your_signed_in_path
end
ログイン済みの場合
先に書いた通りログイン済みの状態でパスワードをリセットすると自動的にログアウトされてしまうため、そのままでは任意のページに飛んでくれません。そこで明示的に一旦ログアウトと再ログインを行うことで遷移が可能になります。
def after_resetting_password_path_for(resource)
bypass_sign_in(resource) if user_signed_in?
your_signed_in_path
end
まとめ
今回のポイントはd以下の2つです。
- 未ログイン規制を解除する
- 明示的に再ログインする
ログイン状態でパスワードを変更するとログアウトになってしまう様ですが、単純に sign_in(resource)
とするだけではログインできず、一旦 sign_out(resource)
を挟むとできました。なんとなくログアウトされているというよりは何かログイン情報が一致しなくてログイン後のページに遷移できていない様な感じがします。。。
ちなみに sign_in(resource)
ではなく、普通に飛ばされた /sign_in
ページでログインするとそれはまたちゃんとログインできるんですよね。どういう仕組みなんだろう???
コメント