
Next.js と Supabase Auth を使っているスキマ勉強アプリに、パスワードリセット機能を実装しました。
ログイン機能を作ったあと、後回しにしがちだったのが「パスワードを忘れたときの導線」です。
でも、学習履歴やお気に入り、復習機能を使うアプリでは、ログインできなくなることはかなり大きなストレスになります。
今回は、Next.js × Supabase Auth でパスワードリセット機能を実装するときに確認したことをまとめます。
実装した全体フロー
今回実装した流れは次の通りです。
1. ログイン画面から「パスワードを忘れた方」へ遷移
2. メールアドレスを入力
3. Supabase Auth でリセットメールを送信
4. メール内のリンクを開く
5. アプリのパスワード再設定ページへ遷移
6. 新しいパスワードを入力
7. Supabase Auth でパスワード更新
8. 完了後にログイン画面へ戻す
実装自体はシンプルですが、実際に作ってみると、リダイレクトURLやエラーメッセージ、メールが届かない場合の表示など、確認すべき点がいくつかありました。
1. パスワードリセット申請ページ
まず、ユーザーがメールアドレスを入力するページを用意します。
例として、以下のようなページを作ります。
/reset-password
このページでは、メールアドレスを入力して、Supabase Auth の resetPasswordForEmail を呼び出します。
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/update-password`,
});
redirectTo には、ユーザーがメール内リンクをクリックしたあとに戻ってくるURLを指定します。
今回は、新しいパスワードを設定するページとして、次のURLを使いました。
/update-password
2. リセットメール送信後のメッセージ
メール送信後は、成功・失敗のメッセージを表示します。
たとえば、成功時は以下のようにします。
パスワード再設定用のメールを送信しました。
メール内のリンクから、新しいパスワードを設定してください。
ここで注意したのは、「登録されているメールアドレスかどうか」を詳しく表示しすぎないことです。
セキュリティ上、メールアドレスの存在確認につながるような文言は避けた方がよいと考えました。
そのため、エラー表示もできるだけ一般的な表現にしました。
メール送信に失敗しました。時間をおいてもう一度お試しください。
3. Supabase側のリダイレクトURL設定
実装でつまずきやすいのが、リダイレクトURLです。
ローカル開発環境と本番環境でURLが違うため、Supabase側でも許可するURLを設定しておく必要があります。
確認したURLは次のようなものです。
http://localhost:3000/update-password
https://自分の本番URL/update-password
Netlifyで公開している場合は、NetlifyのURLも設定対象になります。
https://xxxxx.netlify.app/update-password
リセットメールのリンクをクリックしてもアプリに戻ってこない場合は、まずSupabase側のリダイレクトURL設定を確認するとよいです。
4. パスワード再設定ページ
次に、新しいパスワードを入力するページを作ります。
/update-password
ここでは、ユーザーが新しいパスワードを入力し、Supabase Auth の updateUser を呼び出します。
const { error } = await supabase.auth.updateUser({
password: newPassword,
});
成功したら、ログイン画面へ戻します。
router.push("/login");
実装時には、以下のような入力チェックも入れました。
- パスワードが空でないか
- 確認用パスワードと一致しているか
- 最低文字数を満たしているか
5. エラーメッセージで確認したこと
パスワードリセットでは、いくつかのエラーケースがあります。
確認したのは次のようなケースです。
- メールアドレスが空
- メール形式が不正
- メール送信に失敗
- リセットリンクの有効期限切れ
- パスワードが短すぎる
- 確認用パスワードと一致しない
- パスワード更新に失敗
エラー時は、できるだけユーザーが次に何をすればよいか分かる文言にしました。
たとえば、リンク切れの場合は以下のようにします。
リンクの有効期限が切れている可能性があります。
もう一度パスワード再設定メールを送信してください。
単に「エラーが発生しました」だけだと、ユーザーが次に進めません。
認証まわりでは、エラー文言もかなり大事だと感じました。
6. 実装後の確認項目
実装後に確認した項目です。
- ログイン画面からリセット申請ページへ移動できる
- メールアドレスを入力して送信できる
- リセットメールが届く
- メール内リンクから再設定ページへ移動できる
- 新しいパスワードを設定できる
- 確認用パスワードと一致しない場合にエラーが出る
- 更新後にログイン画面へ戻る
- 新しいパスワードでログインできる
- 古いパスワードでログインできない
- リンク切れや不正リンク時に案内が出る
特に大事なのは、最後のログイン確認です。
パスワード更新が成功したように見えても、実際に新しいパスワードでログインできるか確認しないと安心できません。
7. 実装して感じたこと
パスワードリセットは、見た目としては地味な機能です。
でも、ユーザー目線ではかなり重要です。
パスワードを忘れても戻ってこられる。
学習履歴やお気に入り、復習機能をまた使える。
これは、アプリを安心して使ってもらうための土台だと思いました。
新しい資格コースを追加するような分かりやすい機能も大事ですが、こういう認証まわりの改善も同じくらい大事です。
まとめ
Next.js × Supabase Auth でパスワードリセットを実装するときは、次の点を確認するとよさそうです。
- resetPasswordForEmail でメール送信する
- redirectTo に再設定ページを指定する
- Supabase側でリダイレクトURLを許可する
- 再設定ページで updateUser を使う
- パスワード入力チェックを入れる
- エラーメッセージを丁寧にする
- 新しいパスワードでログインできるか確認する
パスワードリセットは派手な機能ではありません。
でも、ユーザーがアプリに戻ってこられるようにするための大事な機能です。
個人開発でも、こういう小さな安心を少しずつ整えていきたいです。