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

Chron's avatar
Level 6

Route [password.reset] not defined.

I'm having a trouble with the reset password. I have these routes:

Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('admin.password.reset');
Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('customer.password.reset');
Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('other-users.password.reset');

How can I solve this? The reset controllers are using ResetsPasswords trait, so they're empty.

0 likes
25 replies
Snapey's avatar

rename the route.

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

or edit the forms to use your version of the route names

1 like
Chron's avatar
Level 6

edit the forms to use your version of the route names

They're already using their respective routes:

admin.passwords.email view

<form method="POST" action="{{ route('admin.password.email') }}">
    @csrf
    ...
</form>
admin.passwords.reset view

<form method="POST" action="{{ route('admin.password.update') }}">
    @csrf
...
</form>

Should I use the reset routes?

Chron's avatar
Level 6

I have custom logins so I didn't used the auth scaffold

Snapey's avatar

so if you want some help you are going to show more of the error message, or describe what you were doing when it appeared

Cronix's avatar

Try running artisan route:clear in case you have them cached. If they're cached, it won't even look at the route file.

It would be good to show the output of artisan route:list to see what routes/names Laravel is actually using.

El_Orfi_Hiba's avatar

It works for me I was in this problem for 4 days or more thank you a lot

Chron's avatar
Level 6

@cronix I've done that, the error is still there.

@snapey Illuminate/Auth/Notifications/ResetPassword.php Has this line:

->action(Lang::getFromJson('Reset Password'), url(config('app.url').route('password.reset', ['token' => $this->token], false)))

It uses the password.reset route. That may be the one causing the problem.

Nakov's avatar

Every error gives a stacktrace so you should see in your log file what is the line that causes this error to be thrown, that way you will know which routes you need to modify.

So to answer your question above, yes, this is one of the usages that will throw an error in case you use this code, you might need to override this function and adapt the route names.

If you are doing a manual auth, I would rather use my own controllers and leave the same route names instead of changing just the route name, because that does not provides any value whatsoever. As far as I can see above you just changed the route names and you still use the same controllers/actions.

Snapey's avatar

It uses the password.reset route. That may be the one causing the problem.

it should not need to be so vague. The stack trace will tell you where the error is

But back to my first point, why not just change the route name? The url can still be under admin

Chron's avatar
Level 6

why not just change the route name? The url can still be under admin

Ohh, I'm sorry. I didn't understand it at first. I'll try that.

Also, to add some security(?). I would like to add a Rule in the Password Reset.

I have all the users' emails and passwords in a single model, but the table has an column 'type' to determine what type of user he/she is.

For example, I'm in /admin/password/reset and type the email that I want to reset before sending it, I would like to check if the typed email has an account type of "admin", else do not send the email and return an error that the email doesn't exist. I've done that in ForgotPasswordController.php

    protected function validateEmail(Request $request)
    {
        $request->validate([
            'email' => [
                'required','email',
                Rule::exists('accounts')->where(function ($query) {
                    $query->where('account_type', 'Admin');
                }),
            ]
        ]);
    }

But when it didn't pass the validation, it just redirect to the homepage. How can I redirect to the current url?

Edit: Okay, I made a custom rule,


    protected $redirect;

    public function __construct() {

        $this->redirect = url()->current();
    }
    public function rules()
    {
        return [
            'email' => [
                'required','email',
                Rule::exists('accounts')->where(function ($query) {
                    $query->where('account_type', 'Admin');
                }),
            ]
        ];
    }

    public function messages() {
        return [
            'email.required' => 'Email Required.',
        ];
    }

But I'm getting The GET method is not supported for this route. Supported methods: POST.

Edit again: Should I hard code it to 'admin/password/reset'? Because it gets redirected to admin/password/email that's why I'm getting the error. I tried it to admin/password/reset and it worked.

Snapey's avatar

How do you get to the password reset form, what's it URL? There is no redirect involved at any point?

Are you using the showLinkRequestForm function still?

Chron's avatar
Level 6

How do you get to the password reset form, what's it URL?

Yes, I made the form action links, validation redirection hardcoded. Also I also made this:

protected function sendResetLinkResponse(Request $request, $response)
    {
        return back()->with('status', trans($response));
    }

    protected function sendResetLinkFailedResponse(Request $request, $response)
    {
        return back()
                ->withInput($request->only('email'))
                ->withErrors(['email' => trans($response)]);
    }

to

protected function sendResetLinkResponse(Request $request, $response)
    {
        return redirect('admin/password/reset')->with('status', trans($response));
    }

    protected function sendResetLinkFailedResponse(Request $request, $response)
    {
        return redirect('admin/password/reset')
                ->withInput($request->only('email'))
                ->withErrors(['email' => trans($response)]);
    }

Are you using the showLinkRequestForm function still?

Yes, but I override it with my custom view.

I've added a new field in the showLinkRequestForm, and a new rule.

    public function rules()
    {
        return [
            'email' => [
                'required','email',
                Rule::exists('accounts')->where(function ($query) {
                    $query->where('account_type', 'Admin');
                }),
            ],
            'id' => [
                'required', 'numeric',
                Rule::exists('admins'),
            ],
        ];
    }

But the problem with this validation is I can input other ids that exist in admins table and it will send the reset email. What should I do with this?

Snapey's avatar

I thought your checking the user type was working ok, just redirecting to the wrong place?

The other two methods you changed only come into play once the form has been validated - so it won't be those causing redirection to home.

Chron's avatar
Level 6

The other two methods you changed only come into play once the form has been validated - so it won't be those causing redirection to home.

I also changed the redirect of the validation. I hardcoded it with 'admin/password/reset' so if the validation passed or not, it will get redirected to that path.

Chron's avatar
Level 6

Here are the routes now..

Route::namespace('AdminAuth')->group(function (){
            Route::post('login', 'LoginController@login');

            Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.email');
            Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.request');
            Route::post('password/reset', 'ResetPasswordController@reset')->name('password.update');
            Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('password.reset');
});

Route::namespace('CustomerAuth')->group(function (){
            Route::post('login', 'LoginController@login');

            Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.email');
            Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.request');
            Route::post('password/reset', 'ResetPasswordController@reset')->name('password.update');
            Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('password.reset');
});

I don't get the error but when I go reset a customer user I get to another user's reset route.

Chron's avatar
Level 6

Yep, they're prefixed already.

Route::namespace('Admin')->group(function (){
    Route::prefix('admin')->group(function (){
        Route::namespace('AdminAuth')->group(function (){
            Route::post('login', 'LoginController@login');

            Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.email');
            Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.request');
            Route::post('password/reset', 'ResetPasswordController@reset')->name('password.update');
            Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('password.reset');
        });
    });
});


Route::namespace('Customer')->group(function (){
    Route::prefix('customer')->group(function (){
        Route::namespace('CustomerAuth')->group(function (){
            Route::post('login', 'LoginController@login');

            Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.email');
            Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.request');
            Route::post('password/reset', 'ResetPasswordController@reset')->name('password.update');
            Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('password.reset');
        });
    });
});

Chron's avatar
Level 6

The Reset Notification uses this..

route('password.reset', ['token' => $this->token], false)))

I have 6 routes that has the name of password.reset so that's why I'm getting wrong url.

1 like
Snapey's avatar

use php artisan route:list to inspect all the route names

Cronix's avatar

I did suggest that a few days ago. OP claimed he did (but never posted the results).

gabrieldepaula's avatar

Hi, I was experiencing the same issue as you, and the solution I found was to create a new notification for this email and use it in the model.

In my case:

artisan make:notification Employee/ResetPasswordNotification

In the Employee model:

use App\Notifications\Employee\ResetPasswordNotification as EmployeeResetPasswordNotification;

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

In the notification:

public function toMail($notifiable) {
    return (new MailMessage)
        ->line('The introduction to the notification.')
        ->action('Notification Action', route('employee.password.reset', $this->token))
        ->line('Thank you for using our application!');
}

Im using the version 6 of laravel.

2 likes
rajesh.kc681's avatar

Perfect Solution for multi-authentication with multiple guards with different namespaces and routes

MerryChristmas's avatar

@gabrieldepaula

Your solution gives me Undefined property: App\Notifications\ResetPasswordNotification::$token because $this->token is not defined. Why?

If I replace $this->token with for example 123456 the solution works. (but it will of course send me email with link '/reset-password/123456' instead of real token)

How do I make $this->token work?

MerryChristmas's avatar

OK, I think I figured it out.

You have to also in the notification change construct to this:

    public $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

Please or to participate in this conversation.