イントロダクション
多くのWebアプリケーションでは、ユーザーがアプリケーションを使用開始する前に電子メールアドレスを確認する必要があります。Laravelでは、作成するアプリケーションごとにこの機能を手作業で再実装する必要はなく、電子メール確認リクエストを送信および検証するための便利な組み込みサービスを提供しています。
Note:
てっとり早く始めたいですか?Laravelアプリケーションスターターキットの1つを新しいLaravelアプリケーションにインストールしてください。スターターキットは、電子メール確認サポートを含む、認証システム全体のスカフォールドを処理します。
モデルの準備
はじめる前に、App\Models\User
モデルがIlluminate\Contracts\Auth\MustVerifyEmail
契約を実装していることを確認してください。
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
// …
}
このインターフェイスをモデルへ追加したら、新しく登録したユーザーへ、確認リンクを含む電子メールが自動的に送信されます。アプリケーションのApp\Providers\EventServiceProvider
を調べるとわかるように、はじめからLaravelは、Illuminate\Auth\Events\Registered
イベントへアタッチ済みのSendEmailVerificationNotification
リスナを用意してあります。このイベントリスナが、電子メール確認リンクをユーザーへ送信します。
スターターキットを使用する代わりに、アプリケーション内で手作業で登録を実装する場合は、ユーザーの登録が成功した後に、Illuminate\Auth\Events\Registered
イベントを確実に発行してください。
use Illuminate\Auth\Events\Registered;
event(new Registered($user));
データベースの検討事項
次に、users
テーブルにユーザーの電子メールアドレスが確認された日時を格納するためのemail_verified_at
カラムを用意する必要があります。デフォルトでLaravelフレームワークに含まれているusers
テーブルのマイグレーションには、はじめからこのカラムが含まれています。したがって、必要なのはデータベースのマイグレーションを実行することだけです。
php artisan migrate
ルート
電子メール確認を適切に実装するには、3つのルートを定義する必要があります。第1に、Laravelがユーザー登録後に送信する確認メール中のメールアドレス確認リンクをクリックする必要があるという通知をユーザーに表示するためのルートが必要になります。
第2に、ユーザーが電子メール内の電子メール確認リンクをクリックしたときに生成されるリクエストを処理するルートです。
第3に、ユーザーが誤って最初の確認リンクを紛失した場合に、確認リンクを再送信するためのルートです。
メール確認の通知
前述のように、登録後にLaravelがメールで送信するメール確認リンクをクリックするようにユーザーに指示するビューを返すルートを定義する必要があります。このビューは、ユーザーが最初に電子メールアドレスを確認せずにアプリケーションの他の部分にアクセスしようとしたときに表示されます。App\Models\User
モデルがMustVerifyEmail
インターフェイスを実装している限り、リンクは自動的にユーザーへ電子メールで送信されることに注意してください。
Route::get('/email/verify', function () {
return view('auth.verify-email');
})->middleware('auth')->name('verification.notice');
メール確認通知を返すルートの名前は
verification.notice
にする必要があります。Laravelが用意しているverified
ミドルウェアは、ユーザーがメールアドレスを確認していない場合、このルート名に自動的にリダイレクトするため、ルートへ正確にこの名前を割り当てることが重要です。
Note:
電子メール検証を手作業で実装する場合は、検証通知ビューの内容を自分で定義する必要があります。必要なすべての認証ビューと検証ビューを含むスカフォールドが必要な場合は、Laravelアプリケーションスターターキットをチェックしてください。
メール確認のハンドラ
次に、ユーザーが電子メールで送信された電子メール確認リンクをクリックしたときに生成されるリクエストを処理するルートを定義する必要があります。このルートにはverification.verify
という名前を付け、auth
およびsigned
ミドルウェアを割り当てる必要があります。
use Illuminate\Foundation\Auth\EmailVerificationRequest;
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
$request->fulfill();
return redirect('/home');
})->middleware(['auth', 'signed'])->name('verification.verify');
先に進む前に、このルートを詳しく見てみましょう。まず、通常のIlluminate\Http\Request
インスタンスの代わりにEmailVerificationRequest
リクエストタイプを使用していることに気付くでしょう。EmailVerificationRequest
は、Laravelに含まれているフォームリクエストです。このリクエストは、リクエストのid
パラメータとhash
パラメータの検証を自動的に処理します。
次に、リクエスト上のfulfill
メソッドを直接呼び出します。このメソッドは、認証済みユーザーのmarkEmailAsVerified
メソッドを呼び出し、Illuminate\Auth\Events\Verified
イベントを発行します。markEmailAsVerified
メソッドは、Illuminate\Foundation\Auth\User
ベースクラスを介してデフォルトのApp\Models\User
モデルで利用できます。
ユーザーのメールアドレスを検証したら、好きな場所にリダイレクトできます。
メール確認の再送信
たまにユーザーはメールアドレスの確認メールを紛失したり、誤って削除したりすることがあります。これに対応するため、ユーザーが確認メールの再送信をリクエストできるルートを定義できます。次に、確認通知ビュー内にシンプルなフォーム送信ボタンを配置することで、このルートへのリクエストを行うことができるようにしましょう。
use Illuminate\Http\Request;
Route::post('/email/verification-notification', function (Request $request) {
$request->user()->sendEmailVerificationNotification();
return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');
保護下のルート
ルートミドルウェアは、確認済みユーザーのみが特定のルートにアクセスできるようにするために使用できます。Laravelには、Illuminate\Auth\Middleware\EnsureEmailIsVerified
クラスを参照するverified
ミドルウェアが付属しています。このミドルウェアはアプリケーションのHTTPカーネルではじめから登録されているため、必要なのはミドルウェアをルート定義にアタッチすることだけです。通常、このミドルウェアはauth
ミドルウェアと一緒に使います。
Route::get('/profile', function () {
// 確認済みのユーザーのみがこのルートにアクセス可能
})->middleware(['auth', 'verified']);
このミドルウェアが割り当てられているルートに、未確認ユーザーがアクセスしようとすると自動的にverification.notice
名前付きルートにリダイレクトされます。
カスタマイズ
確認メールのカスタマイズ
デフォルトの電子メール確認通知はほとんどのアプリケーションの要件を満たすと思いますが、Laravelでは電子メール確認メールメッセージの構築をカスタマイズできます。
取り掛かるには、Illuminate\Auth\Notifications\VerifyEmail
通知によって提供されるtoMailUsing
メソッドにクロージャを渡します。クロージャは、通知を受信するnotifiableモデルインスタンスと、ユーザーがメールアドレスを確認するためにアクセスする必要のある署名済みのメール確認URLを受け取ります。クロージャは、Illuminate\Notifications\Messages\MailMessage
のインスタンスを返す必要があります。通常、アプリケーションのApp\Providers\AuthServiceProvider
クラスのboot
メソッドからtoMailUsing
メソッドを呼び出す必要があります。
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
/**
* 全認証/認可サービスの登録
*
* @return void
*/
public function boot()
{
// …
VerifyEmail::toMailUsing(function ($notifiable, $url) {
return (new MailMessage)
->subject('Verify Email Address')
->line('Click the button below to verify your email address.')
->action('Verify Email Address', $url);
});
}
Note:
メール通知の詳細は、メール通知ドキュメントを参照してください。
イベント
Laravelアプリケーションスターターキットを使用する場合、Laravelはメール確認プロセス中にイベントを発行します。アプリケーションの電子メール確認を手作業で処理する場合は、確認の完了後にこれらのイベントを手作業で発行することを推奨します。アプリケーションのEventServiceProvider
でこれらのイベントへリスナをアタッチできます。
use App\Listeners\LogVerifiedUser;
use Illuminate\Auth\Events\Verified;
/**
* アプリケーションにマップするイベントリスナ
*
* @var array
*/
protected $listen = [
Verified::class => [
LogVerifiedUser::class,
],
];