前回まででページをプロテクトする処理が実装できたので、今回はパスワードを変更する処理を実装していきます。
パスワードリセットメール送信処理の実装
パスワードリセットメールの送信
pagesフォルダ内にforgot-password.vueという名前でファイルを作成し以下の様に編集します。forgot-passwordにpostしているだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<template> <form @submit.prevent="sendForgotPasswordEmail"> <v-text-field type="text" name="email" id="email" v-model="form.email" label="メールアドレス" /> <v-btn type="submit">パスワードリセット</v-btn> </form> </template> <script> export default { auth: false, data() { return { form: { email: "", }, }; }, methods: { async sendForgotPasswordEmail() { try { await this.$axios.get("sanctum/csrf-cookie"); await this.$axios.post("forgot-password", this.form); } catch (e) {} }, }, }; </script> |
見た目はこんな感じになります。
cors対策としてconfig\cors.phpのpathsに'forgot-password'の追加もしておきます。
エラー発生:Route [password.reset] not defined.
これだけ・・・と思ったのですがやってみたら「 "message": "Route [password.reset] not defined.", 」というエラーが発生してしまいました。
なんやかんや調べてみるとapp\Providers\AuthServiceProvider.phpを以下の様に編集することで解消されました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Gate; use Illuminate\Auth\Notifications\ResetPassword; class AuthServiceProvider extends ServiceProvider { /** * The policy mappings for the application. * * @var array */ protected $policies = [ // 'App\Models\Model' => 'App\Policies\ModelPolicy', ]; /** * Register any authentication / authorization services. * * @return void */ public function boot() { $this->registerPolicies(); ResetPassword::createUrlUsing(function ($user, string $token) { return env('HOME_URL') . '/reset-password?email=' . $user->email . '&token=' . $token; }); } } |
詳説
DevToolsで表示されているResetPassword.phpの100行目を見てみるとpassword.resetという名前のルートを使って何かしようとしてるけどそんなルートは定義していないのでエラーになっているようです(以下画像の97行目)。
少し前(93行目)でstatic::$createUrlCallbackメソッドを呼んでいるので、これを設定しているcreateUrlUsingメソッド(109行目)でこれを定義してあげれば良さそうと思いました。
ググってみると以下のページが見つかったので試しに前述のように設定してみたらいい感じに動いてくれました。
パスワードリセット 8.x Laravel (readouble.com)
再実行
再度実行してみるとちゃんとメールが飛ぶことが確認できました。リンク先もcreateUrlUsingメソッドで指定した宛先になっています。
パスワードリセット処理の実装
リセットメールの送信処理が実装できたので、次は実際にリセットするページを作成します。リセットメール内でページ名はreset-passwordとしておいたのでpagesフォルダ内にreset-password.vueという名前でファイルを作成し以下の様に編集します。
reset-passwordにpostするだけです。config\cors.phpのpathsに'reset-password'の追加も忘れずしておいてください。リセットメール内のリンクURLで、URLパラメータにメールアドレスとリセット用のトークンがセットされているのでそれをpostしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<template> <form @submit.prevent="resetPassword"> <v-text-field type="text" name="email" id="email" v-model="form.email" label="メールアドレス" /> <v-text-field type="password" name="password" id="password" v-model="form.password" /> <v-text-field type="password" name="password_confirmation" id="password_confirmation" v-model="form.password_confirmation" /> <v-btn type="submit">パスワード設定</v-btn> </form> </template> <script> export default { auth: false, data() { return { form: { email: this.$route.query.email || "", password: "", password_confirmation: "", token: this.$route.query.token || "", }, }; }, methods: { async resetPassword() { try { await this.$axios.get("sanctum/csrf-cookie"); await this.$axios.post("reset-password", this.form); } catch (e) {} }, }, }; </script> |
テスト
あまりUIを作りこんでいないので分かりづらいですがこんな感じに動作します。
最後に
簡単にパスワードのリセット処理を実装することが出来ました。実際はかなり悩んでますが分かってしまえば非常に手間なく実装できることが分かるかと思います。どこかの誰かの同じ悩みを解消出来たら幸いです。 次回はやるつもりなかったけどユーザー認証メールのカスタマイズを実装してみようと思います。