【Laravel5.7】Email Verificationの使い方

#Email Verificationの機能

1. メールアドレスとパスワード（+α）を入力してもらう
2. 入力されたメールアドレスに仮登録のメールを送信
3. 仮登録に書かれたURLにアクセスすると本登録が完了

最近よくあるユーザ登録時の流れ。

#実装
##ユーザー登録できるようセットアップ
###make:auth

```terminal:terminal
php artisan make:auth
```

###migrate

```terminal:terminal
php artisan migrate
```

##Email Verification機能を使えるようにする
###MustVerifyEmailの追加

```diff:app/User.php
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

+class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}
```

###Routeの変更

* `Auth::routes();`部分の変更
* `verified`を使って「本登録したユーザーだけが表示できるページ」を登録

```diff:routes/web.php
<?php

Route::get('/', function () {
    return view('welcome');
});

+Auth::routes(['verify' => true]);

Route::get('/home', 'HomeController@index')->name('home');

+Route::middleware('verified')->group(function() {
+    // 本登録ユーザーだけ表示できるページ
+    Route::get('verified',  function(){
+        return '本登録が完了してます！';
+    });
+});
```

Registerから会員登録をしてみます。

###WEB
仮登録が完了して、ログイン後の画面が出てきます。
<img width="1056" alt="スクリーンショット 2018-12-17 15.03.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/7e35d509-5078-f9f8-e1c3-c59dc091e968.png">


###メール
登録したメールアドレスに下の画像のようなメールが届きます。
<img width="509" alt="スクリーンショット 2018-12-17 15.08.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/8f3a6af4-31cd-ca28-9177-25d64a7708c0.png">


##修正
メールアドレス未確認なのに、ログイン後の画面が出てしまうので、
「メール送信しました」的な画面が出るようにしたいと思います。

`->middleware('verified')`を設定。
メール確認ができてない状態で、homeにアクセスされた場合はemail/verifyにリダイレクトさせます。

###ルーティングの修正

```diff:routes/web.php
+Route::get('/home', 'HomeController@index')->middleware('verified');
```

もう一度アカウント登録を試すと、以下の画面になると思います。
<img width="892" alt="スクリーンショット 2018-12-17 15.17.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/19042b61-495f-389b-fc75-842bc189ad91.png">


とりあえず、これで設定は完了です。

##メール文や画面文を日本語に修正したい
詳しい内容は[【Laravel5.6】インストール直後にやること3点](https://blog.capilano-fw.com/?p=289)を参考にするといいかと思います。

###本登録を促すページ
修正前
<img width="499" alt="スクリーンショット 2018-12-17 15.32.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/98360677-ae26-e0a1-8bdf-0b5af30c65ad.png">


修正後
<img width="499" alt="スクリーンショット 2018-12-17 15.31.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/1b8b5b2d-89df-9523-6914-042332191439.png">

再送信リンクをクリックすると出てくるアラート
<img width="499" alt="スクリーンショット 2018-12-17 15.33.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/be5763c6-3b46-f8c4-abb7-71f029422d17.png">


```diff:resources/views/auth/verify.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">本登録</div>

                <div class="card-body">
                    @if (session('resent'))
                        <div class="alert alert-success" role="alert">
                            新しい本登録メッセージが送信されました。
                        </div>
                    @endif

                    メールアドレスの認証をお願いします。<br>
                    もしメールを受け取ってないなら、<a href="{{ route('verification.resend') }}">ここをクリックしてください</a>。
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
```

###本登録メール
`Notification`を作る

```terminal:terminal
php artisan make:notification VerifyEmailJapanese
```

```diff:app/Notifications/VerifyEmailJapanese.php
<?php

namespace App\Notifications;

use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Lang;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class VerifyEmailJapanese extends Notification
{
    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable);
        }

        return (new MailMessage)
            ->subject(Lang::getFromJson('本登録メール'))
            ->line(Lang::getFromJson('以下の認証リンクをクリックして本登録を完了させてください。'))
            ->action(
                Lang::getFromJson('メールアドレスを認証する'),
                $this->verificationUrl($notifiable)
            )
            ->line(Lang::getFromJson('もしこのメールに覚えが無い場合は破棄してください。'));
    }

    /**
     * Get the verification URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
            'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
        );
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }
}
```

###`VerifyEmailJapanese`が本登録メールで送信されるように、app/User.phpに記述

```diff:app/User.php
// Override
public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Notifications\VerifyEmailJapanese);
}
```
届いたメールを確認すると、以下の画像のようになりました。
<img width="511" alt="スクリーンショット 2018-12-17 15.46.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/252667/b37e08c1-f411-14fd-308b-d71a9c7af076.png">

本文にまだ英語の部分が残っていますが、この設定は[【Laravel5.6】インストール直後にやること3点](https://blog.capilano-fw.com/?p=289)にも記載があります。



とりあえず以上です。

##参考記事

* [Laravel5.7のEmail Verification（本登録メール）の使い方](https://blog.capilano-fw.com/?p=1099#i-7)
* [【Laravel 5.7】新たにメールアドレスの確認機能(Email Verification)が追加。使い方と仕組みを紹介します。](https://public-constructor.com/laravel57-email-verification/)