[Laravel] Email Verification(メールアドレスの確認機能)の使い方とカスタマイズについて
先日のLaravel5.7
のリリースで新しく追加されたEmail Verificationがとても便利ですので紹介します。
今までのLaravelでは、フレームワーク内に認証機能が実装されており、これを有効にすることで簡単にログイン機能等を利用することができました。
デフォルトの挙動では、ユーザーの新規作成(/register
ページ)後にそのままログインが可能になるというフローでした。
認証付きのサービス等でよく見る、ユーザーの新規作成時に登録されたメールアドレスが正確かどうかを確認するフロー(本登録メール等)をはさみたい場合には、自前で実装するかサードパーティーのパッケージを利用する必要がありました。(josiasmontag/laravel-email-verificationl等)
メールアドレスが正確かどうかの確認は、サービス上でユーザーとのやりとりが発生する場合においてとても重要です。
この機能がついにLaravelで実装されました。
Email Verificationの利用方法
ドキュメントに書いてある通り、使い方はとても簡単です。
App\User
モデルへIlluminate\Contracts\Auth\MustVerifyEmail
インターフェイスと、Illuminate\Auth\MustVerifyEmail
トレイトを追加します。
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
class User extends Authenticatable implements MustVerifyEmailContract
{
use Notifiable, MustVerifyEmail;
/**
* 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',
];
}
認証ルートの作成は今まで通りphp artisan make:auth
コマンドを実行し、routes/web.php
ファイルに認証のためのルートが追加されます。
追加されたAuth::routes();
に引数を渡すように変更します。
// 変更前
// Auth::routes();
// 変更後
Auth::routes(['verify' => true]);
Tips
Auth::routes()
メソッド(Auth
ファサードでIlluminate\Routing\Router
クラスのauth
メソッドが呼ばれる)の処理が以下のように変更されてメールアドレス確認用のルーティングが追加されています。
/**
* Register the typical authentication routes for an application.
*
* @param array $options
* @return void
*/
public function auth(array $options = [])
{
// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
// Registration Routes...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');
// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
// Email Verification Routes...
if ($options['verify'] ?? false) {
$this->emailVerification();
}
}
後は認証が確認なルートのmiddleware
にverified
を指定するだけです。(すべての認証ルートに適用する場合にはauth
ミドルウェアをverified
ミドルウェアに置き換えるだけです)
Route::middleware(['verified'])
->group(function() {
Route::get('example', function() {
return 'Access';
});
});
Laravel 5.6からアップデートした際には以下の作業が必要です
新しくLaravel5.7
をインストールした場合には不要ですが、それ以前のバージョンからアップデートを行った場合には下記作業を行ってください。
1. VerificationControllerをapp/Http/Controllers/Auth/VerificationController.php
へ配置
2. app/Http/Kernel.php
の$routeMiddleware
へIlluminate\Auth\Middleware\EnsureEmailIsVerified
を追加
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
3. app/Providers/EventServiceProvider.php
にIlluminate\Auth\Listeners\SendEmailVerificationNotification
イベントを追加
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}
認証周りのイベントについてはこちらで説明しています。
4 database/migrations/2014_10_12_000000_create_users_table.php
にemail_verified_at
の追加
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
設定ができたら、/register
へアクセスして新規登録を行いましょう。
登録したメールアドレスへ認証メールが届きます。
確認メールのカスタマイズ
確認メールの送信はIlluminate\Auth\Notifications\VerifyEmail
クラスで行います。
標準では英語の文面ですが、メールの構文にはIlluminate\Translation\Translator
クラスが使用されているため、オリジナルの言語ファイルを設置することにより文面のカスタマイズが行えます。
以下のファイルをapp/resources/lang/ja.json
として保存してください。
{
"Hello!": "こんにちは",
"Verify Email Address": "メールアドレスの確認",
"Please click the button below to verify your email address.": "以下をクリックして、メールアドレスの確認を行ってください。",
"If you did not create an account, no further action is required.": "このメールの内容に身に覚えがない場合は、このまま破棄してください。",
"Regards": "宜しくお願い致します",
"If you’re having trouble clicking the \":actionText\" button, copy and paste the URL below\ninto your web browser: [:actionURL](:actionURL)": "\":actionText\" ボタンが機能しない場合は, こちらのURLをブラウザにコピーして貼り付けてください: [:actionURL](:actionURL)"
}
config/app.php
のlocale
をja
に指定している場合に、設定した日本語でメールが送られてきます。
Tips
メールの送信そのものをオリジナルにカスタマイズする場合には、toMailUsing()
メソッドで送信処理をコールバックで渡すことができます。
app/Providers/AppServiceProvider.php
等でオリジナルのコールバックを指定しましょう。
<?php
namespace App\Providers;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
VerifyEmail::toMailUsing(function ($notifiable) {
$verifyUrl = URL::temporarySignedRoute(
'verification.verify', now()->addMinutes(60), ['id' => $notifiable->getKey()]
);
return (new MailMessage())
->subject('Your subject')
->line('Whatever you like')
->action('Verify it', $verifyUrl);
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}