Laravel 5.7 email verification expiration time
Asked Answered
S

3

8

I would like to customize the time users have to verify their email address that happens through the built in Auth (since 5.7).

In config/auth there is:

'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

But I haven't found anything similar for email verification. There is also no mention in the official documentation.

Starstarboard answered 5/12, 2018 at 15:48 Comment(1)
I doubt there is such an option.Alodie
R
7

In deed the options is not there in Laravel, but since laravel makes use of the following:

  • a trait MustVerifyEmail (in Illuminate\Foundation\Auth\User class extended by the main User model)

  • Event and Notification

In the MustVerifyEmail trait, there's a method called sendEmailVerificationNotification. This is where the Notification VerifyEmail class referenced by @nakov's answer and its function verificationUrl is used:

/**
 * Send the email verification notification.
 *
 * @return void
 */
public function sendEmailVerificationNotification()
{
    $this->notify(new Notifications\VerifyEmail);
}

Since we know this, we can do the following:

  • Extend the Notifications\VerifyEmail to our custom VerifyEmail class
  • override the implementation of verificationUrl
  • override the implementation of the sendEmailVerificationNotification method in the User model to use our new VerifyEmail class.

Having done the above, our User model will have the following method:

/**
 * Send the email verification notification.
 *
 * @return void
 */
public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Services\Verification\VerifyEmail);
}

Now we make use of our custom VerifyEmail class. Then our new VerifyEmail class would look like this:

namespace App\Services\Verification;

use Illuminate\Support\Carbon;
use \Illuminate\Support\Facades\URL;

class VerifyEmail extends \Illuminate\Auth\Notifications\VerifyEmail
{
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
            'verification.verify', Carbon::now()->addMinute(3), ['id' => $notifiable->getKey()]
        );  //we use 3 minutes expiry
    }
}

Well, apart from the explanations, the process is quite straight forward. I hope it is easy to grasp. Cheers!

Ruvalcaba answered 5/12, 2018 at 18:0 Comment(0)
A
18

Whilst the question specifically addresses Laravel 5.7, I feel that it is worth mentioning that as of Laravel 5.8, it is possible to achieve this with a config variable. My search for customising the verification expiration time returned this question as the top result, hence my addition.

If we check out Illuminate\Auth\Notifications\VerifyEmail, the verificationUrl method now looks like this:

protected function verificationUrl($notifiable)
{
    return URL::temporarySignedRoute(
        'verification.verify',
        Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
        ['id' => $notifiable->getKey()]
    );
}

As such, we can just add this block to config/auth.php to customise the time without needing to extend the classes or anything:

'verification' => [
    'expire' => 525600, // One year - enter as many mintues as you would like here
],

UPDATE: I've written about the above approach, as well as another on customising the process by overiding the verificationUrl method to give you more flexibility, on my blog.

Amperage answered 8/7, 2019 at 0:46 Comment(0)
R
7

In deed the options is not there in Laravel, but since laravel makes use of the following:

  • a trait MustVerifyEmail (in Illuminate\Foundation\Auth\User class extended by the main User model)

  • Event and Notification

In the MustVerifyEmail trait, there's a method called sendEmailVerificationNotification. This is where the Notification VerifyEmail class referenced by @nakov's answer and its function verificationUrl is used:

/**
 * Send the email verification notification.
 *
 * @return void
 */
public function sendEmailVerificationNotification()
{
    $this->notify(new Notifications\VerifyEmail);
}

Since we know this, we can do the following:

  • Extend the Notifications\VerifyEmail to our custom VerifyEmail class
  • override the implementation of verificationUrl
  • override the implementation of the sendEmailVerificationNotification method in the User model to use our new VerifyEmail class.

Having done the above, our User model will have the following method:

/**
 * Send the email verification notification.
 *
 * @return void
 */
public function sendEmailVerificationNotification()
{
    $this->notify(new \App\Services\Verification\VerifyEmail);
}

Now we make use of our custom VerifyEmail class. Then our new VerifyEmail class would look like this:

namespace App\Services\Verification;

use Illuminate\Support\Carbon;
use \Illuminate\Support\Facades\URL;

class VerifyEmail extends \Illuminate\Auth\Notifications\VerifyEmail
{
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
            'verification.verify', Carbon::now()->addMinute(3), ['id' => $notifiable->getKey()]
        );  //we use 3 minutes expiry
    }
}

Well, apart from the explanations, the process is quite straight forward. I hope it is easy to grasp. Cheers!

Ruvalcaba answered 5/12, 2018 at 18:0 Comment(0)
B
4

If you open the Illuminate\Auth\Notifications\VerifyEmail::class;

The method that generates the URL already uses expiration time which defaults to 1 hour. Unfortunately there is no option to modify that value.

/**
 * Get the verification URL for the given notifiable.
 *
 * @param  mixed  $notifiable
 * @return string
 */
protected function verificationUrl($notifiable)
{
    return URL::temporarySignedRoute(
        'verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
    );
}
Bombshell answered 5/12, 2018 at 16:19 Comment(1)
Thanks, It was not mentioned on the documentation.Walston

© 2022 - 2024 — McMap. All rights reserved.