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:
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:
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.
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!