railsでdevise_token_authを利用したパスワードリセットについて、少しハマりましたので記事にまとめます。
僕たち2人が開発しているサービスfootlogは、
のようにビューとサーバー処理を分けて開発しており、ログイン機能の実装にはトークンベースのdevise_token_authを利用しています。
この記事は以下の実行環境で動作確認しています。
パスワードをリセットするためのリンクを生成するPOST /auth/password
で生成されたメールリンクを踏むと、以下のメッセージ(devise_token_authが生成したjson)が表示されてしまい、redirect_url
に埋め込んだフロントエンドのページにリダイレクトしてくれません。
最初は、フロントエンド側でredirec_url
をリクエストボディに含めていないことを疑いましたが、以下のとおりリクエストボディにredirect_url
をのせてリクエストを送信しています。
// フロントのソースの一部抜粋
axios.post(`${process.env.REACT_APP_API_ENDPOINT}/auth/password`,{
email: email,
redirect_url: `http://localhost:3001/user/password/reset`
})
また、サーバ側のログでは以下のように表示されていて、パラメーターに、redirect_url
があることが確認できます。
Started POST "/v1/auth/password" for ::1 at 2022-01-03 09:18:00 +0900
Processing by DeviseTokenAuth::PasswordsController#create as HTML
Parameters: {"email"=>"sample@sample.com", "redirect_url"=>"http://localhost:3001/user/password/reset", "password"=>{"email"=>"sample@sample.com", "redirect_url"=>"http://localhost:3001/user/password/reset"}}
Unpermitted parameters: :redirect_url, :password
Unpermitted parameters: :redirect_url, :password
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."uid" = $1 AND "users"."provider" = $2 LIMIT $3 [["uid", "sample@sample.com"], ["provider", "email"], ["LIMIT", 1]]
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."reset_password_token" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["reset_password_token", "e90cecdf60fde14f5f20d918aaf9ceb2679e79fffc90aa50ac5e2d9cbb82982f"], ["LIMIT", 1]]
(0.1ms) BEGIN
User Update (0.4ms) UPDATE "users" SET "reset_password_token" = $1, "reset_password_sent_at" = $2, "updated_at" = $3 WHERE "users"."id" = $4 [["reset_password_token", "e90cecdf60fde14f5f20d918aaf9ceb2679e79fffc90aa50ac5e2d9cbb82982f"], ["reset_password_sent_at", "2022-01-03 00:18:00.658245"], ["updated_at", "2022-01-03 00:18:00.658579"], ["id", 5]]
(0.8ms) COMMIT
edit_password_url
メソッドを使って、リンク先を生成していないことが原因でした。
devise_token_authのドキュメントを確認すると、ちゃんと記載されていました。
送信用メールのビューを生成して、edit_password_url
メソッドを使ってリンクを生成することで解決することができます。
devise_token_authが生成するメールを編集するために、以下のコマンドを実行します。
rails generate devise_token_auth:install_views
このコマンドを実行すると、以下の2つのビューが生成されます。
app/views/devise/mailer/reset_password_instructions.html.erb
app/views/devise/mailer/confirmation_instructions.html.erb
公式ドキュメントには、ここに記載があります。
app/views/devise/mailer/reset_password_instructions.html.erb
を開き、リンクを記載したい箇所に以下を追記します。
<%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url'].to_s).html_safe %>
ビューの編集については、こちらに記載されています。
以上で、無事、メールで送られてくるリンクを踏むと、redirect_url
に設定したURLにリダイレクトしてくれるようになりました。
少し公式ドキュメントが分かりづらいような気もしますが、ドキュメントをしっかり読まないといけないことを学びました。
困ったら、ググるだけでなく、公式ドキュメントを確認しましょう。
以上です。