Dorokhov.codes
Examples: email verification
If you check events and listeners in your app:
php artisan event:list
you will see that Illuminate\Auth\Listeners\SendEmailVerificationNotification
listener is always
waiting for the Illuminate\Auth\Events\Registered
event.
Illuminate\Auth\Events\Registered
⇂ Illuminate\Auth\Listeners\SendEmailVerificationNotification
...
Here’s how this listener looks like:
<?php
namespace Illuminate\Auth\Listeners;
use Illuminate\Auth\Events\Registered;
use Illuminate\Contracts\Auth\MustVerifyEmail;
class SendEmailVerificationNotification
{
/**
* Handle the event.
*
* @param \Illuminate\Auth\Events\Registered $event
* @return void
*/
public function handle(Registered $event)
{
if ($event->user instanceof MustVerifyEmail && ! $event->user->hasVerifiedEmail()) {
$event->user->sendEmailVerificationNotification();
}
}
}
As you can see, to enable email verification sending, the App\Models\User
model should
implement the Illuminate\Contracts\Auth\MustVerifyEmail
contract.
<?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;
// ...
}
Here’s the contract (interface) class:
<?php
namespace Illuminate\Contracts\Auth;
interface MustVerifyEmail
{
/**
* Determine if the user has verified their email address.
*
* @return bool
*/
public function hasVerifiedEmail();
/**
* Mark the given user's email as verified.
*
* @return bool
*/
public function markEmailAsVerified();
/**
* Send the email verification notification.
*
* @return void
*/
public function sendEmailVerificationNotification();
/**
* Get the email address that should be used for verification.
*
* @return string
*/
public function getEmailForVerification();
}
These methods are already implemented in the default App\Models\User
class (inherited from the parent Illuminate\Foundation\Auth\User
class).
There is also a trait for this: Illuminate\Auth\MustVerifyEmail
. In fact, it’s used in the Illuminate\Foundation\Auth\User
class.
Database Preparation
Your users
table must contain an email_verified_at
column to store the date and time that the user’s email address was verified.
Routing
To properly implement email verification, three routes will need to be defined.
/email/verify
: to display a notice to the user that they should click the email verification link in the verification email that Laravel sent them after registration./email/verify/{id}/{hash}
: to handle requests generated when the user clicks the email verification link in the email./email/verification-notification
: to resend a verification link if the user accidentally loses the first verification link.
The Email Verification Notice
Route::get('/email/verify', function () {
return view('auth.verify-email');
})->middleware('auth')->name('verification.notice');
The verified
middleware included with Laravel will automatically redirect to this route name (verification.notice
) if a user has not verified their email address.
The Email Verification Handler
Next, we need to define a route that will handle requests generated when the user clicks the email verification link that was emailed to them. This route should be named verification.verify
.
use Illuminate\Foundation\Auth\EmailVerificationRequest;
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
$request->fulfill();
return redirect('/');
})->middleware(['auth', 'signed'])->name('verification.verify');
The form request class Illuminate\Foundation\Auth\EmailVerificationRequest
checks parameters
and the fulfill()
method which does the logic for verification.