5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Laravel7でユーザー認証_8】メールアドレス変更時にメール認証を行う

Last updated at Posted at 2020-06-25

#はじめに
Laravelのユーザー認証機能を利用する際、会員がメールアドレスを変更したら、メール認証を実行する手順をまとめます。

環境

XAMPP環境でLaravelが使えるように設定してあります。

  • Windows10 Pro 64bit
  • PHP 7.3.18
  • Laravel 7.12.0
  • MariaDB 10.1.32

また、Laravelプロジェクトは以下の手順で作業を進めており、会員登録時にメール認証を行う段階までできている状態です。

実装手順

##メールアドレス変更時、メール認証をリセットする

メールアドレスを変更する処理の中に、メール認証をリセットする処理(email_verified_at をNULLにする)を追加します。

app/Http/Controllers/SettingController.php
      public function changeEmail(ChangeEmailRequest $request)
      {
        //ValidationはChangeUsernameRequestで処理
        //メールアドレス変更処理
        $user = Auth::user();
        $user->email = $request->get('email');
+       $user->email_verified_at = null;
        $user->save();

        //homeにリダイレクト
        return redirect()->route('setting')->with('status', __('Your email address has been changed.'));
      }
  }

##認証メールを送信する

メール認証のリセット処理の後、引き続き認証用のメールを送信します。
ユーザー登録時の処理をなぞってみると、認証用のメールはUsers クラスの sendEmailVerificationNotification メソッドで送れるようです。

notify を使って $user->notify(new VerifyEmail()); という書き方もできそうです。
その場合は use Illuminate\Auth\Notifications\VerifyEmail; を忘れずに。

処理完了のメッセージも変更しておきます。

app/Http/Controllers/SettingController.php
      public function changeEmail(ChangeEmailRequest $request)
      {
        //ValidationはChangeUsernameRequestで処理
        //メールアドレス変更処理
        $user = Auth::user();
        $user->email = $request->get('email');
        $user->email_verified_at = null;
        $user->save();
+       $user->sendEmailVerificationNotification();

        //homeにリダイレクト
-       return redirect()->route('setting')->with('status', __('Your email address has been changed.'));
+       return redirect()->route('setting')->with('status', __('A confirmation email for changing the email address has been sent.'));
      }
  }

##同じメールアドレスの場合、何も処理せずに完了表示とする

メールアドレスの変更処理を行った際、同じメールアドレスであれば特に処理せずに「完了しました」と表示させたいと思います。
(エラー表示にしたい場合は、FormRequestwithValidator を定義するとよさそうです。)

app/Http/Controllers/SettingController.php
      public function changeEmail(ChangeEmailRequest $request)
      {
        //ValidationはChangeUsernameRequestで処理
        //メールアドレス変更処理
        $user = Auth::user();
+ 
+       if ($user->email == $request->get('email')){
+           return redirect()->route('setting')->with('status', __('Your email address has been changed.'));
+       }
+
        $user->email = $request->get('email');
        $user->email_verified_at = null;
        $user->save();
        $user->sendEmailVerificationNotification();

        //homeにリダイレクト
        return redirect()->route('setting')->with('status', __('A confirmation email for changing the email address has been sent.'));
      }
  }

##日本語対応

resources/lang/ja.json
+     "A confirmation email for changing the email address has been sent.": "メールアドレス変更の確認メールを送信しました。"
  }

##未認証の場合もメールアドレス変更フォームを使えるよう変更

認証が通っていないユーザーも、メールアドレス変更のフォーム表示 showChangeEmailForm と処理changeEmail ができるように、__construct の定義を変更します。
(ここで表示部分だけ許可したがために、ハマりました……。)

->except で複数指定したいので、配列にして渡します。

app/Http/Controllers/SettingController.php
      public function __construct()
      {
          $this->middleware('auth');
-         $this->middleware('verified')->except('index');
+         $this->middleware('verified')->except(['index', 'showChangeEmailForm', 'changeEmail']);
      }

viewについても、リンクが切れないように修正します。

resources/views/setting/index.blade.php
                        <a href="{{ route('email.form') }}"
-                       @if ($auth->email_verified_at)
                          class="list-group-item list-group-item-action d-flex justify-content-between align-items-center"
-                       @else
-                          class="list-group-item list-group-item-action d-flex justify-content-between align-items-center disabled" tabindex="-1" aria-disabled="true"
-                       @endif
                        >
                          <dl class="mb-0">
                            <dt>{{ __('E-Mail Address') }}</dt>
                            <dd class="mb-0">{{ $auth->email }}</dd>
                          </dl>
-                         @if ($auth->email_verified_at)
                          <div><i class="fas fa-chevron-right"></i></div>
-                       @endif
                        </a>

##動作確認

▼メールアドレスを変更した直後の表示。認証ができていなくても、アカウント削除とメールアドレス変更は利用可能。
Laravel-MustVerifyEmail-05.png

▼認証済ユーザーが、同じメールアドレスで変更処理した場合、特に処理せず完了メッセージ表示。
Laravel-MustVerifyEmail-06.png

#参考サイト

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?