Let’s face it, Laravel doesn’t come with a elegant way to let the User change his email securely, but for some reason it has a verification email. May be the framework doesn’t expect the User to change its email? Who knows.

Most of the time, when users want to change the email, the application can face a problem in the database: the email is already taken over by other user, because is unique. This low-level restriction alleviates much of the headaches of multiple users sharing one account.

But not having one mechanism ready out of the box doesn’t mean we can create our own.

How this pans out

When the user changes his email for other, we will check first if the new email is not already used, which will trigger an “invalid email” error.

Then, we will dispatch an notification to the new email, using a Temporary Signed URL to validate the change, that will last one hour. When he goes to the new URL, the controller will change the email.

For this to work we need next to nothing. No packages to install, or migrations to run, not even the Cache.

Receiving the change in the Controller

We will create a EmailChangeController with two methods. One will send the email, and the other will complete the email change.

Okay, we have a change method, that creates the email change, and the verify method, that verifies and completes the change.

The first will verify the email is not already used, send the email, and return your view saying that the email was sent. The notification will be sent to the new email using the on-demand feature, and we will pass the User ID to identify who is changing the email.

The second method automatically verifies the URL, and then changes the email using the User ID parameter. We can leave the returned view to detect if the user is authenticated to redirect via JavaScript to its dashboard or not.

The notification

Here is where the magic happens.

We created a method that conveniently creates an Temporary Signed URL to change the email. So when the notification goes out, it will use the User ID we saved inside this instance, the email of the notifiable object, and pass it to the email view being sent — in this case we’re using a convenient markdown email.

I’m not going into details about the views and email template, since this will depend on the application itself, but is pretty straightforward.