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

FabioPacifici's avatar

Password reset link, incorrect format and Invalid token - Laravel 5.7 Multi language

Hello everyone, and thanks in advance for your time.

I am working on a multi-language site, and all seems working fine until I started doing the reset password views.

I have two issues, where I would appreciate your help as I didn't manage to figure out what's wrong:

  1. The button inside the password reset email has an incorrect format: localhost/{token}/password/reset instead of localhost/{locale}/password/reset/{token}

  2. Why when I visit the page typing the password reset URL correctly into the browser like localhost/en/password/reset/token-token, and submit the form the validation fails and returns the password reset token is invalid?

On the reset.blade.php view, the request returns the locale “en” instead of the password reset token value.

What would be the best practice here? Should I make a new notification class for the password reset link to fix the point one?

Given that I type the URL manually into the browser, then shouldn't the password reset token validation work as it is?

Inside the web.php routes file I have the following routes:

Route::get('/password/email/', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.email');
        Route::post('/password/email/', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');

        Route::get('/password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
        Route::post('/password/reset', 'Auth\ResetPasswordController@reset')->name('password.reset');

The password.reset view looks like posts to the following route:

                    <form method="POST" action="{{ route('password.reset', app()->getLocale()) }}">


The ResetPasswordController:


<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;

class ResetPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Where to redirect users after resetting their password.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    public function redirectTo()
    {
        return app()->getLocale() . '/home';
    }

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }
}

0 likes
11 replies
larafever's avatar

Route::post('/password/reset', 'Auth\ResetPasswordController@reset')->name('password.reset');

this needs to be refactored to

php
Route::post('/password/reset/{token}', 'Auth\ResetPasswordController@reset')->name('password.reset');

using this way, I presume that password.reset route is in a route group that enforce locale prefixing

php

Route::group(["prefix"=>"en"],function(){

//sub routes here

});
FabioPacifici's avatar

@LARAFEVER - Hi Larafever, thanks for your reply. Yes, the routes are in a group with a prefix, however passing the {token} to the post request on the reset method for the ResetPasswordController makes the request to fail.

thanks anyway for your time. Cheers

1 like
FabioPacifici's avatar
FabioPacifici
OP
Best Answer
Level 12

Finally figured all out, if anyone needs it:

Issue 1:

To adjust the link of the button inside the password reset email body we need to:

make a new password reset notification class Edit the ResetPassword notification class and its constructor to accept the token Overide the method on the user model Let’s start by making a new notification class using the following artisan command:

php artisan make:notification ResetPassword

Then we modify the file in app/Notifications/ResetPassword.php in the following way:

use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification; 

Above we import the new ResetPassword notification class then change class in the following way, adding the extends ResetPasswordNotification and token inside the construct like so:

class ResetPassword extends ResetPasswordNotification
{
use Queueable;
public $token;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($token)
{
$this->token = $token;
}

Continuing in the same file, we need to edit the toMail method like so:

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
$locale = app()->getLocale();
return (new MailMessage)
->subject('Reset your password - ' . config('app.name'))
->line('Hey this email was sent to you because you requested a password change for your order.')
->action('Reset Password', url($locale . '/password/reset', $this->token))
->line(' if you did not request a password change, please ignore this email.');
}

Now we need to override the method sendPasswordResetNotification inside the User class, in the file app/Http/User.php

First we Import the new ResetPassword class at the top

use App\Notifications\ResetPassword;

Then we Override the method

public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPassword($token));
}

Issue 2:

On the reset.blade.php view, the request returns the locale “en” instead of the password reset token value.

If I dd($request->all()) on the ResetPasswordController@reset method this is what I was gettting:

array:5 [▼
“_token” => “YrwPp06e6dV3iVlyQ59y1lvcNvOwCoQr0bIyAwgX”
“token” => “en”
“email” => “[email protected]”
“password” => “password”
“password_confirmation” => “password”
]

This is solved by Changing the showResetForm method from:

         public function showResetForm(Request $request, $token = null)
            {
                return view('auth.passwords.reset')->with(
                    ['token' => $token, 'email' => $request->email]
                );
            }

To:

  public function showResetForm(Request $request, $token = null)
            {
        $token = $request->token;

        return view('auth.passwords.reset')->with(
            ['token' => $token, 'email' => $request->email]
        );
        }

I wrote a complete multi-language guide for future reference, it's available on my site: https://fabiopacifici.com/laravel-5-7-multi-language-complete-guide/

5 likes
leopauldubourg@gmail.com's avatar

@FabioPacifici I don't understand in which file you write your function showResetForm to solve the second problem In app/Notifications/ResetPassword.php ?

FabioPacifici's avatar

@leopauldubourg@gmail.com the showResetForm is a method that goes inside the ResetPasswordController that you can find in Controllers/Auth.

Sanojan's avatar

@FabioPacifici Hi, Your explanation is working fine for me. But when I recieve email notification the URI is generated without email. (i.e:mysite.com/en/password/reset/sample-token). So, when I click the link password reset form opens without email filled in email text box. In showResetForm method I did dd($request->email()), it shows null. Can you help me to fix this?

FabioPacifici's avatar

@Sanojan email should be accessed as a property from the $request not as method. Try dd($request->email) instead. If still null please post your showResetForm method code here so I can have a look

bondif's avatar

Thank you so much, I had the same problem when working with subdomains.

Please or to participate in this conversation.