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

Hesto's avatar
Level 5

[Laravel 5.3] Change URL in reset password link with Mulit Auth

I want to change url which is hardcoded in Illuminate\Auth\Notifications\ResetPassword. The change must be done in Model class, becouse different models could have diffrent urls for reset passwords (multi auth).

   /**
     * Build the mail representation of the notification.
     *
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail()
    {
        return (new MailMessage)
            ->line('You are receiving this email because we received a password reset request for your account.')
            ->action('Reset Password', url('password/reset', $this->token)) // <- this url
            ->line('If you did not request a password reset, no further action is required.');
    }

One way is to override in Model's class sendPasswordResetNotification from use Illuminate\Auth\Passwords\CanResetPassword but i am doing it for my Laravel 5.3 multi-auth package (https://github.com/Hesto/multi-auth) and i think its a bad idea to create new class especially for that reset email.

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

Do you have any idea how can i handle it? I can't let it go because when i reset password with my package, for example from admin guard, i get wrong reset link.

0 likes
24 replies
Hesto's avatar
Hesto
OP
Best Answer
Level 5

Well i think there is no other good way to handle it, so i just implemented sendPasswordResetNotification() with custom Password reset notification. It works fine.

ajmerainfo's avatar

Can you please explain in detail how you did it?

I have same issue.

Hesto's avatar
Level 5

@ajmerainfo Sure i can. The easiest way is to install my package and use it https://github.com/Hesto/multi-auth . If you don't want use it in your project. Just install laravel fresh copy, install my package then use install command with name of guard you already have. If your guard's name is admin just type in console:

php artisan multi-auth:install admin -f

Then copy:

  • sendPasswordResetNotification method from app/Admin.php
  • a file app/Notifications/AdminResetPassword.php
  • content of controllers into your controllers, from app/Http/Controllers/AdminAuth/

And paste it into your project. Reset passwords will work fine.

1 like
ajmerainfo's avatar

Thank you @hesto This repo is great. It's really easy to use. It took me few days to understand multi auth in Laravel. with this repo I can make multi auth for admin in sec. You rock :)

1 like
Hesto's avatar
Level 5

@ajmerainfo You're welcome :). I just made new version, its minor change in code but very important. I wrote everything in changelog but i will paste it here.

v1.0.4

  • added name and prefix to route group configuration in RouteServiceProvider
Route::group([
    'prefix' => 'admin', //if you have older version of package (< v1.0.4) add this line manually,
    'as' => 'admin.', //if you have older version of package (< v1.0.4) add this line manually (the DOT at the end is important), 
    'middleware' => ['web', 'admin'],
    'namespace' => $this->namespace,
], function ($router) {
    require base_path('routes/admin.php');
});
  • Now you will be able to name your routes without adding guard's name to route name in your routes/{guard}.php and your routes will be named (its important)
//New way
Route::get('/home', function () { // <- no {guard} prefix and it has proper name (admin.home)
    //content
})->name('home'); // http://your-project/admin/home

//Old way
Route::get('/admin/home', function () { // <- with {guard} prefix
    //content
})->name('admin.home'); // http://your-project/admin/home
Hesto's avatar
Level 5

@ajmerainfo you have to create {guard} _role table foreach guard. Thanks to laravel 5.3 auth changes Auth::user() always return currently logged in user (even when use custom guard) so entrust is finally good solution for ACL with multi auth. Entrust dont work well with laravel 5.2 multi auth. I dont know another packages with multi auth, that was the reason why i made it.

ajmerainfo's avatar

Thank you @HeXiaodong & @Hesto ,

Is there any way I can use "Auth" class like "Auth::admin()"? Currently we have to use like "Auth::guard('admin')"

Hesto's avatar
Level 5

@ajmerainfo if you are logged in as User Auth::user() will return User class. If you are logged in as Admin Auth::user() will return Admin class.

ajmerainfo's avatar

@Hesto I have tried but it gave me null.

Route::get('/admin/home', function () { dd(Auth::user());

//dd(Auth::guard('admin')->user());  // This give proper result.

});

Hesto's avatar
Level 5

Sorry my fault. It should be

Auth::guard()->user();

You just don't have to name the guard.

ajmerainfo's avatar

Hi @Hesto,

It's still give me null result.

Route::get('home', function () {
    dd(Auth::guard()->user());
});
Hesto's avatar
Level 5

@ajmerainfo Well, i was sure that i did it before, but i can't repeat it. It just doesn't work. When i find solution ill tell you.

Hesto's avatar
Level 5

@ajmerainfo i just found solution. The problem was RouteServiceProvider where i forgot about auth:{guard} middleware. I will add it to my multi-auth packages soon, and you can fix it manually:

    Route::group([
            'middleware' => ['web', 'admin', 'auth:admin'], //you need to add the last middleware to array to fix it
            'prefix' => 'admin',
            'as' => 'admin.',
            'namespace' => $this->namespace,
        ], function ($router) {
            require base_path('routes/admin.php');
        });

And now you can use whatever you want to get user:

    Auth::user();
    Auth::guard()->user();
    Auth::guard('admin')->user();
    auth()->user();
    //etc, every method works fine
1 like
ajmerainfo's avatar

@Hesto

You are awesome. You saved from adding so many extra hacks in code.

It's working great.

Just one more thing I have generated admin multi-auth user and when I try to access any page with route/admin.php It call one database query with each request. Is that normal or am I missing something?

select * from `admins` where `admins`.`id` = ? limit 1
Hesto's avatar
Level 5

@ajmerainfo You're welcome :).

It looks like it fetch authenticated user and thats why you can use Auth::user() with any guard. But i'm not sure. I will check it later.

ajmerainfo's avatar

@Hesto

Need small help. How can I get current guard name from anywhere?

Example I want like this Auth::guard()->name

ajmerainfo's avatar

I did like below code but I don't get Auth::guard()->name

Route::group([
            'middleware'    => ['web', 'admin', 'auth:admin'],
            'prefix'        => 'admin',
            'as'            => 'admin.',
            'namespace'     => $this->namespace,
        ], function ($router) {
            require base_path('routes/admin.php');
        });
Hesto's avatar
Level 5

@ajmerainfo What do you exactly want to do? You have access to guard's name from middlewares. Look at RedirectIfAuthenticated or RedirectIfNotAdmin middleware.

ajmerainfo's avatar

@Hesto

I have created my own role and permission module for generalize users like admin or any other users.

I am try to get guard name example "admin" on my role class then coding will use role/permission for "admin" user.

See below class I create trait "UserRolePermsTrait" and I am passing "$roleTableStartWith = 'admin';" hard coded. want to avoid that one guard name. I am trying to get that dynamic on base of guard name. Many roles permissions table connected based on guard name.

class Admin extends Authenticatable
{
    use Notifiable;
    use UserRolePermsTrait;

    /**
     * Table name start with. User for multi-auth purpose
     * Ex. Default 'user' but for admin it can be 'admin'
     * 
     * @var string
     */
    protected $roleTableStartWith = 'admin';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

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

In trait I have to write coding like below with "$this->roleTableStartWith"

trait UserRolePermsTrait
{
    /**
     * Many-to-Many relations with Role.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles()
    {
        return $this->belongsToMany(
            'App\\' . ucfirst($this->roleTableStartWith) . 'Role',
            $this->roleTableStartWith . '_role_user', $this->roleTableStartWith . '_id', $this->roleTableStartWith . '_role_id');
    }
}
Hesto's avatar
Level 5

@ajmerainfo Just keep it simple :). You made simple thing realy complicated and i think you dont benefits from that complication. Make pivot table for each guard. admin_role, role_user etc.

Please or to participate in this conversation.