- Guides
Implementing Dmarc – A Step-by-Step Guide
Connor Leech, our guest author, is a Software Engineer over at Stitch Labs. You can contact him through his email.
The newly released Laravel version 5.7 adds a new capability to verify user’s emails. If you’ve ever run php artisan make:auth
within a Laravel app you’ll know the feeling of pleasure and excitement when you see all of your register and login pages, complete with password hashing and a users table already built out.
This excitement will soon subside after deploying to production only to find that anyone can register with garbage@notrealemail.com
or whatever they feel like typing in. This thin session authentication layer doesn’t help much in a live application. The introduction of Laravel 5.7’s MustVerifyEmail
interface adds to the authentication scaffold so that in order for users to log in, they must use a real, valid email address.
The first step is to create a new application with some setup:
1$ laravel new email-verification-example2$ php artisan make:auth3Authentication scaffolding generated successfully.4$ touch database/database.sqlite
This will create the default Laravel 5.7 app with the authentication scaffold and a file for an SQLite database. Update your .env file to point to the full path of the SQLite file:
1DB_CONNECTION=sqlite2DB_DATABASE=/full/path/to/email-verification-example/database/database.sqlite
Let’s inspect the default auth scaffold and see what changes need to be made to add email verification.
You can view the Laravel Email Verification docs
The first step is to implement the MustVerifyEmail interface. An interface in PHP specifies the methods a class must implement.
1<?php23namespace App;45use Illuminate\Notifications\Notifiable;6use Illuminate\Contracts\Auth\MustVerifyEmail;7use Illuminate\Foundation\Auth\User as Authenticatable;89class User extends Authenticatable implements MustVerifyEmail10{11 ...12
That interface enforces that we have three new methods on our User model:
hasVerifiedEmail()
markEmailAsVerified()
sendEmailVerificationNotification()
The implementations for these methods can be found in vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php. To mark a user as verified, we need to have an email_verified_at
column on our users table, which is already provided in our default create users table migration:
1Schema::create('users', function (Blueprint $table) {2 $table->increments('id');3 $table->string('name');4 $table->string('email')->unique();5 $table->timestamp('email_verified_at')->nullable();6 $table->string('password');7 $table->rememberToken();8 $table->timestamps();9});
Run the migrations to create the table: php artisan migrate
In the routes/web.php file update the authentication routes to include email verification:
1Auth::routes(['verify' => true]);
To view all the routes available to your application you can run php artisan route:list
. That’s pretty much all we need to do from the Laravel side to verify emails. If you try it now though, it won’t work.
Before we can send emails from our PHP server we need to configure a mail driver within Laravel.
You can check though using tinker to see that a user was created with an email_verified_at of null.
1$ php artisan tinker2Psy Shell v0.9.9 (PHP 7.1.7 — cli) by Justin Hileman3>>> $users = App\User::all();
Be sure to consult the Laravel docs on sending Email
Learn about our Deliverability Services
Looking to send a high volume of emails? Our email experts can supercharge your email performance. See how we've helped companies like Lyft, Shopify, Github increase their email delivery rates to an average of 97%.
Mailgun offers the ability to send emails via SMTP server or over their API. In this tutorial, we’re going to send emails via the Mailgun API. It’s faster, scales better, and takes less work to set up than configuring SMTP.
How to Start Sending Email from the Mailgun docs
We’re going to be sending API calls. For that we need Guzzle:
$ composer require guzzlehttp/guzzle
In order for our application to send emails: we need a hosted domain name. I have a domain name that I bought through Google Domains for about $12/year. The site (https://employbl.com/) is hosted on Laravel Forge for a monthly fee. To get it deployed I followed the Laracasts course, Learn Laravel Forge:
Learn Laravel Forge series on Laracasts
In that course, I set up my Laravel application to run off Digital Ocean droplets. In that process I configured my Google Domain name to point to Digital Ocean like so:
Instead of Google’s DNS servers, I am using Digital Ocean’s.
So, even though I bought my domain name through Google Domains I configured my domain name server on the Digital Ocean side.
If you’re interested in how to hook up a custom domain to Laravel Forge I recommend this (free) video.
Once you’ve created a Mailgun account, you’ll need to verify your domain, which takes about 24 hours.
To do that, we need to add TXT, CNAME and MX records. If the MX records are already pointed to a mailbox provider, you can configure a subdomain instead. To find these records go to the domain in your Mailgun account and check Domain Verification & DNS.
Once you have a working Mailgun domain, head to the dashboard to find your API key. Update the .env file accordingly:
MAIL_DRIVER=mailgun
MAILGUN_DOMAIN=mg.YOUR_DOMAIN.com
MAILGUN_SECRET=YOUR_KEY_HERE
Once email sending is configured, after a user registers they will see a landing page asking them to check their email. This page can be modified in resources/views/auth/verify.blade.php.
Landing page if the user has not verified their email.
That will send a real email to the address you provided. The template for this email exists in Illuminate\Auth\Notifications\VerifyEmail.php.
Default verification email sent to the user after they register.
If we don’t want our verification emails to say “Regards” or the above text then we need to customize them. You can publish the default templates using the below publish commands:
1$ php artisan vendor:publish --tag=laravel-notifications2$ php artisan vendor:publish --tag=laravel-mail
Then write the new defaults in resources/views/vendor/notifications/email.blade.php. If you have more to change you could re-implement the notification by adding a new sendEmailVerificationNotification
method to your User model that returns a custom notification that you make.
Once the user clicks the Verify Email Address link they’ll be redirected to their dashboard able to login without issue.
Dashboard once the user has verified their email.
That should have you going! The most difficult part for me was getting the mail server and Mailgun configured. After your domain is verified and Mailgun is all set up the Laravel part ends up being straightforward.
Have you been able to get up and running? Is anyone using this functionality in production yet? Hit me up on Twitter or leave comments below.
I found these tutorials, in addition to the links above to be very helpful.
Last updated on May 12, 2021
Implementing Dmarc – A Step-by-Step Guide
The Science and Art of Gmail Deliverability
The Basics of SPF Records
Understanding DKIM: How It Works and Why It's Necessary
My Email Isn’t Authentic Enough - Misfit Email Series
What Is BIMI? More Than A Funny Name
Email Authentication: Your ID Card For Sending
Become an Email Pro With Our Templates API
How to Conduct a Comprehensive Email Deliverability Audit
Dark Mode for Email Survey: What Do Email Senders Think?
InboxReady x Salesforce: The Key to a Stronger Email Deliverability
Become an Email Pro With Our Templates API
Google Postmaster Tools: Understanding Sender Reputation
Navigating Your Career as a Woman in Tech
Implementing Dmarc – A Step-by-Step Guide
Email Bounces: What To Do About Them
Announcing InboxReady: The deliverability suite you need to hit the inbox
Black History Month in Tech: 7 Visionaries Who Shaped The Future
How To Create a Successful Triggered Email Program
Designing HTML Email Templates For Transactional Emails
InboxReady x Salesforce: The Key to a Stronger Email Deliverability
Implementing Dmarc – A Step-by-Step Guide
Announcing InboxReady: The deliverability suite you need to hit the inbox
Designing HTML Email Templates For Transactional Emails
Email Security Best Practices: How To Keep Your Email Program Safe
Mailgun’s Active Defense Against Log4j
Email Blasts: The Dos And Many Don’ts Of Mass Email Sending
Email's Best of 2021
5 Ideas For Better Developer-Designer Collaboration
Mailgun Joins Sinch: The Future of Customer Communications Is Here
Always be in the know and grab free email resources!
By sending this form, I agree that Mailgun may contact me and process my data in accordance with its Privacy Policy.