Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

getvma's avatar
Level 49

How to customize password reset email in Laravel 5.3

I originally added this issue in github: https://github.com/laravel/framework/issues/14496

Here is that post;

I am running a Dual Auth:Guard application.

in the frontend routes i use the standard auth() scaffold and install.

// routes/web.php
// using default middleware and guard
Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index');

The backend route has the following;

//  middleware 'web, auth:admin'
// prefixed 'admin' in RouteServiceProvider

// Authentication Routes...
Route::group(['namespace' => 'Admin\Auth'], function (\Illuminate\Routing\Router $router) {

    // Login...
    $router->get('login', ['as'=>'admin.login', 'uses'=>'LoginController@showLoginForm']);
    $router->post('login', 'LoginController@login')->name('admin.login');
    $router->get('logout', ['as'=>'admin.logout', 'uses'=>'LoginController@logout']);

    // Registration Routes...
    if (config('cms.app.allow_admin_user_registration')) {
        $router->get('register', 'RegisterController@showRegistrationForm')->name('admin.register');
        $router->post('register', 'RegisterController@register');
    }

    // Password Reset Routes...
    $router->get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('admin.password.reset');
    $router->post('password/email', 'ForgotPasswordController@sendResetLinkEmail');
    $router->get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('admin.password.token');
    $router->post('password/reset', 'ResetPasswordController@reset');
});

I copied all App\Http\Controllers\Auth* into App\Http\Controllers\Admin\Auth\ and customized guards and brokers as per the documentation. Additionally i created all customized views inside its own backend\auth path.... and... made all of the other configurations to support multiple auth guards.

Everything works! ..... Almost!

The password reset email link that is sent by the system only directs the user to the '/password/reset' path. which uses the default guard and default redirects. In order for admins to succefully reset their password the path needs to change to '/admin/password/reset' so that the link can use the correct auth guard and redirects as customized on those controllers.

There is a resetNotifier() method in the SendsPasswordResetEmails trait but there is no documentation as to how to use it. I understand that it can be overwritten in ForgotPasswordController.php but exactly what you do inside of resetNotifier() escapes me. Or, perhaps its not even related..

The actual email message is embedded in the following Notifications class which i think is pretty darn cool...

namespace Illuminate\Auth\Notifications;

use Illuminate\Notifications\Notification;

class ResetPassword extends Notification
{
    /**
     * The password reset token.
     *
     * @var string
     */
    public $token;

    /**
     * Create a notification instance.
     *
     * @param  string  $token
     * @return void
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the notification's channels.
     *
     * @param  mixed  $notifiable
     * @return array|string
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the notification message.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\MessageBuilder
     */
    public function message($notifiable)
    {
        return $this->line('You are receiving this email because we received a password reset request for your account. Click the button below to reset your password:')
                    ->action('Reset Password', url('password/reset', $this->token).'?email='.urlencode($notifiable->email))
                    ->line('If you did not request a password reset, no further action is required.');
    }
}

I am looking for some guidance on this issue.

Thanks Victor

0 likes
12 replies
getvma's avatar
getvma
OP
Best Answer
Level 49

So finally I came back to this and did a full trace of what was going on and I figured it out..

The short is create an override of the sendPasswordResetNotification($token) method on your User Model.

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

Override the ResetPasswordNotification implementation by using your own Notification class.

namespace App;

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

class User extends Authenticatable
{
    use Notifiable;
}

And of course youd probably do this first is create the Notification class;

php artisan make:notification MyOwnResetPassword

BTW, you should probably first copy the original notification which is in ResetPassword.php an \Illuminate class. Also this is not a full complete overwrite of the entirety of the email but just the notification's message. Creating an entirely different email, html and all is a different topic all together.

28 likes
bestmomo's avatar

I dont think that this notification and the english text will stay hard coded in core.

gocanto's avatar

that did the trick for me.

I got a question, do you know what resource I can read about this matter ?

getvma's avatar
Level 49

It was relatively new at the time I figured out what was going on, so there were no resources available then. I had been playing with the 5.3 {develop} branch for a month. I simply traced the code and phpstorm was a huge help. However, here is the documentation in regards to the Notification service: https://laravel.com/docs/5.3/notifications.

Understanding how the scaffolded Auth actually works internally is a matter of diving into the code.

nathanpurcell's avatar

For anyone else having trouble with this kind of situation (CMS/admin/dual login areas) I recommend taking your time and reading the docs thoroughly and digging down into the Illuminate namespace. I've got a great appreciation for Taylor and Laravel but the documentation for me is sometimes too compressed to read easily. But that's probably just me.

If you look at the updated docs for Resetting passwords in L5.3, Taylor does mention a way to customise the reset email. You need to generate your own Notification and override the sendPasswordResetNotification method on the appropriate model (in my case this was the default User model and I'll extend it to my Customer model later).

When I first read about the Notifications feature and tried it out I was a bit surprised to NOT see any mention of having multiple email layouts (granted, on the whole they will probably be the same, but I like flexibility) - however after digging around I saw that there is a view() method available on the MailMessage class. That means if you did want to totally customise the appearance of an email (maybe separating the style of admin emails vs customer emails) you could do something like this:

return (new MailMessage)
            ->view('notifications::myNotificationView')
            ->line('You are receiving this email because we received a password reset request for your account.')
            ->action('Reset Password', url('admin/password/reset', $this->token))
            ->line('If you did not request a password reset, no further action is required.');

Hope this helps someone in the future

5 likes
Yefferson's avatar

Hi there,

If anyone wants to edit the email view (according to their branding needs for example) as @getvma said "Creating an entirely different email, html and all is a different topic all together", it can be made incredible simple, just run:

php artisan vendor:publish

and this will publish the views neccesaries to update them (/resources/views/vendor/notificions). Amazing! By the way, for more details, Jeffrey explain the notifications in laracast episode https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/9 (The publish in 9:15 more or less), and also this topic was checked over here: https://laracasts.com/discuss/channels/laravel/laravel-536-how-to-replace-password-reset-mail-with-custom-mailable-template?page=1

PS. If you only want the 'notify' default email, simply run:

php artisan vendor:publish --tag=laravel-notifications
3 likes
aurawindsurfing's avatar

Hi,

Even simpler method to change default email would be not to use the default mail system but a webhook to an external mail system to do that just go to

Illuminate\Auth\Notifications\ResetPassword

replace

public function via($notifiable)
    {
        return ['mail'];
    }

with lets say

public function via($notifiable)
    {
        return [WebhookChannel::class];
    }

add this funtion below like so

public function toWebhook($notifiable)
    {
        return WebhookMessage::create()
            ->data([xxxxxxxxxxxx])
            ->userAgent("Custom-User-Agent")
            ->header('api-key', env([xxxxxxxxxxxxxxx]'));
    }
}

and you are good to go, same for password reminder etc. This way you will edit your templates outside of laravel templating system and just provide data to the emails.

I for instance use Sendinblue and I find this much better then using build in email driver.

Cheers

einnar82's avatar

how to get the $token from the customized email notification?

should i pass

$this->notify(new ResetPassword($token))

Please or to participate in this conversation.