Laravel/UI: Implement Email Verification

In Laravel applications using the laravel/ui (link) package for authentication, the feature for verifying an email address after registration is built-in but is not enforced by default. To implement email verification, follow the steps below:

1. Implement MustVerifyEmail Interface

Ensure that your User model implements the MustVerifyEmail interface, which will enforce the user to verify their email.

use <span class="hljs-type">Illuminate</span>\<span class="hljs-type">Contracts</span>\<span class="hljs-type">Auth</span>\<span class="hljs-type">MustVerifyEmail</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Authenticatable</span> <span class="hljs-title">implements</span> <span class="hljs-title">MustVerifyEmail</span></span>
    <span class="hljs-comment">// ...</span>

2. Use the Email Verification Middleware

In your routes/web.php file, make sure to use the auth and verified middleware on routes that require a verified email address.

<span class="hljs-keyword">use</span> <span class="hljs-title">Illuminate</span>\<span class="hljs-title">Support</span>\<span class="hljs-title">Facades</span>\<span class="hljs-title">Route</span>;

Route::get(<span class="hljs-string">'/dashboard'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
    <span class="hljs-comment">// Only verified users may access this route...</span>
})->middleware([<span class="hljs-string">'auth'</span>, <span class="hljs-string">'verified'</span>]);

3. Migrate Changes to Database

Ensure your users table has an email_verified_at column to store the timestamp when the user verified their email. If you don't have it, you may need to create a migration to add this column.

php artisan make:migration add_email_verified_at_to_users_table --<span class="hljs-keyword">table</span>=users

In the generated migration file, you might add something like this:

<span class="hljs-selector-tag">public</span> <span class="hljs-selector-tag">function</span> <span class="hljs-selector-tag">up</span>()
    <span class="hljs-attribute">Schema</span>::<span class="hljs-built_in">table</span>(<span class="hljs-string">'users'</span>, function (Blueprint $table) {
        $table-><span class="hljs-built_in">timestamp</span>(<span class="hljs-string">'email_verified_at'</span>)<span class="hljs-built_in">-</span>><span class="hljs-built_in">nullable</span>()<span class="hljs-built_in">-</span>><span class="hljs-built_in">after</span>(<span class="hljs-string">'email'</span>);

Then run the migration:

<span class="hljs-attribute">php artisan migrate</span>

4. Email Verification Notification

Laravel uses notifications to send the email verification link. Ensure that your User model uses the Notifiable trait.

use <span class="hljs-type">Illuminate</span>\<span class="hljs-type">Notifications</span>\<span class="hljs-type">Notifiable</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Authenticatable</span> <span class="hljs-title">implements</span> <span class="hljs-title">MustVerifyEmail</span></span>
    use <span class="hljs-type">Notifiable</span>;

    <span class="hljs-comment">// ...</span>

Customizing Behavior

  • Customizing Verification Email: You may customize the verification email by modifying the toMail method on the VerifyEmail notification.
  • Redirecting After Verification: If you want to customize the redirect after the email is verified, you may define a redirectTo method or property on the EmailVerificationController.
<span class="hljs-keyword">protected</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">redirectTo</span><span class="hljs-params">()</span>
    <span class="hljs-comment">// Your redirect logic here...</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">'/home'</span>;

Optional Email Verification

If you want to make email verification optional:

  • Custom Middleware: Instead of using the built-in verified middleware, you could create a custom middleware that checks if the user has verified their email and acts accordingly (e.g., showing a persistent reminder to verify the email).
  • User Settings: Add an option in the user's settings that allows them to toggle whether they want to verify their email. Be mindful of how this affects your app's security and communication.
  • Conditional Routes: You could add conditional logic to your routes or controllers to handle non-verified users distinctly.

Leave a Reply

Your email address will not be published. Required fields are marked *