How to send the password reset link via email using queue in laravel 5

In case you get "Call to a member function onQueue() on null" after trying to specify queue fakemeta's solution just specify the the queue you are targeting in the constructor of your class.

<?php
namespace App;

use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;

class ResetPasswordNotification extends ResetPassword implements ShouldQueue
{
    use Queueable;

    public function __construct()
    {
        $this->queue = "authentication";
    }
}

then use the notification facade to send your mail in the overriding method. The notify method also works

<?php
namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\ResetPasswordNotification;

class User extends Authenticatable
{
    public function sendPasswordResetNotification($token)
    {
        // either of the two work
        // $this->notify(new ResetPasswordNotification($token));
        \Notification::send($this, new ResetPasswordNotification($token));
    }
}

This is where the Laravel container comes to the rescue. If you don't like the functionality of a core component then you can go ahead and override it fairly painlessly.

First things first you will need to create your own PasswordBroker:

namespace App\Auth\Passwords;

use Illuminate\Auth\Passwords\PasswordBroker as IlluminatePasswordBroker;

class PasswordBroker extends IlluminatePasswordBroker
{

    public function emailResetLink()
    {
        $view = $this->emailView;

        return $this->mailer->queue($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
            $m->to($user->getEmailForPasswordReset());
            if (! is_null($callback)) {
                call_user_func($callback, $m, $user, $token);
            }
        });
    }

}

Change your namespace to whatever you want if you want to place it elsewhere in your app.

Since the service provider registering the service is a deferred service provider you will need to create your own provider to replace it. Probably the easiest way to do this is extend Illuminate\Auth\Passwords\PasswordResetServiceProvider with something like the following:

namespace App\Providers;

use App\Auth\Passwords\PasswordBroker;

class PasswordResetServiceProvider extends \Illuminate\Auth\Passwords\PasswordResetServiceProvider
{

    protected function registerPasswordBroker()
    {
        $this->app->singleton('auth.password', function ($app) {
            $tokens = $app['auth.password.tokens'];

            $users = $app['auth']->driver()->getProvider();

            $view = $app['config']['auth.password.email'];

            return new PasswordBroker(
                $tokens, $users, $app['mailer'], $view
            );
        });
    }

}

Finally in your config/app.php file remove Illuminate\Auth\Passwords\PasswordResetServiceProvider::class and add App\Providers\PasswordResetServiceProvider::class to your 'providers' array.

Laravel will now use your implementation of the PasswordBroker rather than the stock framework one and you don't have to worry about modifying framework code.


I know this has been answered but I found another way to queue password reset notification which I found much more simple. I've tested it on Laravel 5.3 and 6.x.

By default, password reset notification is implemented by Illuminate\Auth\Notifications\ResetPassword class. This class is instantiated in your User model in sendPasswordResetNotification method and passed to notify method of Illuminate\Notifications\Notifiable trait.

So, to queue password reset notification you can simply create new ResetPassword notification class via artisan make:notification ResetPassword and replace it's code with this:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;

class ResetPassword extends ResetPasswordNotification implements ShouldQueue
{
    use Queueable;
}

And now just override sendPasswordResetNotification method in your App\User class:

<?php

...
use App\Notifications\ResetPassword as ResetPasswordNotification;
...    

/**
 * Send the password reset notification.
 *
 * @param  string  $token
 * @return void
 */
public function sendPasswordResetNotification($token)
{
    $this->notify(new ResetPasswordNotification($token));
}