Manually verifying created users when using Laravel Email Verification

Laravel 5.7 ships with bundled Email Verification. This is great if you want to make sure a user’s email address is valid (or at least that the user can access it) before allowing them access.

Problem:
What if you want to manually verify a user without sending them an email address? For example you might want to add or import a load of existing ‘known-good’ users to a migrated app. Or you might be creating Admin or System users that don’t really have accessible email addresses. There could be many reasons.

At present as soon you register a user, the sendEmailVerificationNotification method is called. There’s a good breakdown of how this works in this Stack Overflow answer. If a user is manually created, then when they try to log in they’ll still see the “Verify your email address” message:

Laravel's email verification message

Solutions:
Whether a user has verified their email address or not is indicated by a timestamp in the email_verified_at column of the User table¹. If this column is set to a valid timestamp upon user creation, the user will be ‘validated’ and no email will be sent. So… how can we set that timestamp? 

Option 1 – making `email_verified_at` fillable:
If you are creating a user manually, at the time of creation you could manually set the email_verified_at column to a valid timestamp. To do that email_verified_at could be added to the $fillable array in the model. For example in app/User.php:

protected $fillable = [
    'name', 'email', 'password', 'email_verified_at',
];

…and then the value could be set as part of the Create method used to create the user. e.g:

$user = User::create([
    'name' => 'Mr Benn',
    'email' => 'user@example.com',
    'password' => Hash::make('password'),
    'email_verified_at' => now() //Carbon instance
]);

This is a bit cheesy though, we can do this without changing what’s fillable.

Option 2 – using `forceCreate()`:
If you want to leave the $fillable array alone, forceCreate() can be used like so:

$user = User::forceCreate([
    'name' => 'Mr Benn',
    'email' => 'user@example.com',
    'password' => Hash::make('password'),
    'email_verified_at' => now() //Carbon instance
]);

Option 3 – use the `markEmailAsVerified()` method:
If the user needs to be verified after creation then the markEmailAsVerified() could be used. Here are two examples:

$user = User::create([
    'name' => 'Mr Benn',
    'email' => 'user@example.com',
    'password' => Hash::make('password')
]);

$user->markEmailAsVerified();
$user = User::where('email', $email)->first();
$user->markEmailAsVerified();

Any questions to corrections? Please leave a comment. If this was useful, I’d love to know with a click: Nope, not helpful...Yep, more useful than not! - +3 thumb, 3 overall.
Loading...

Footnotes:
1. This apples to whichever Authenticatable user model/table you are using. If you don’t have this column, check over the setup info in the Email Verification docs.

One thought on “Manually verifying created users when using Laravel Email Verification”

  1. Ugh- I’ve been digging for days trying to find Option 3! I knew there was a method for it but couldn’t find it anywhere online.
    Thank you so much!

Leave a Reply

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