DEV Community

Cover image for Redirect after login in Laravel.
Ariel Mejia
Ariel Mejia

Posted on • Edited on

Redirect after login in Laravel.

Hi, in this post I will dive in the auth scaffold to redirect users to different areas by roles.

Add Role column to users.

User migration:

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('role')->default('user');
            $table->rememberToken();
            $table->timestamps();
        });
    }
Enter fullscreen mode Exit fullscreen mode

User model:

class User extends Authenticatable
{
    use Notifiable, HasApiTokens;

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

AuthController

By adding the auth scaffold, Laravel provide us with Auth controllers for authentication, register, forgot password, etc, the controllers are located in "app/Http/Controllers/Auth", here we can find the "LoginController.php" file, here we can find the property:

protected $redirectTo = RouteServiceProvider::HOME;
Enter fullscreen mode Exit fullscreen mode

This means that we can find a RouteServiceProvider const named "HOME", we can override this const and it will change the redirect endpoint after login, but this is not what we need to redirect users by role or by any other condition.

The LoginController use a trait:

use AuthenticatesUsers;
Enter fullscreen mode Exit fullscreen mode

This AuthenticatesUsers trait has another trait "RedirectsUsers" this RedirectsUsers trait has a method "redirectPath":

public function redirectPath()
{
    if (method_exists($this, 'redirectTo')) {
        return $this->redirectTo();
    }

    return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
Enter fullscreen mode Exit fullscreen mode

So it means that this trait looks if the class has a "redirectTo" property and if this is not the case it execute a "redirectTo" method, so we can add the method "redirectTo" in LoginController to add any logic that we need.

By example:

public function redirectTo()
{
    $for = [
        'admin' => 'admin.panel',
        'user'  => 'foundations.splashscreen',
    ];
    return $this->redirectTo = route($for[auth()->user()->role]);
}
Enter fullscreen mode Exit fullscreen mode

Here you can see an array with roles as keys and route name as value, I strongly suggest that use the "route()" method, because if you change the endpoint it does not affect this method, because the value that we are resolving dinamically is the route name, not the endpoint.

Note:

If you need to use some "dd()" debug the endpoint that will be redirect you can go to the trait "AuthenticatesUsers.php" that is used by "LoginController" here we can find a method "sendLoginResponse", that use the method redirectPath():

protected function sendLoginResponse(Request $request)
{
    $request->session()->regenerate();

    $this->clearLoginAttempts($request);

    if ($response = $this->authenticated($request, $this->guard()->user())) {
        return $response;
    }
    // HERE YOU CAN ADD a dd($this->redirectPath())
    return $request->wantsJson()
                ? new Response('', 204)
                : redirect()->intended($this->redirectPath());
}
Enter fullscreen mode Exit fullscreen mode

Note:

If you want to redirect authenticated users on authentication routes by role to different paths, just edit the "RedirectIfAuthenticated" middleware to redirect by different roles.

Top comments (3)

Collapse
 
sicklounet profile image
Brenier Arnaud

Hello Ariel.

Thanks for the post.

I noticed that the login page needs to be the entry point for the user.
If i'm not logged and use the root url "mydomain.app", I'm redirected to "mydomain.app/login", then I log in, and since my first intended URL was the root one, the redirection is override by the root one.

I found this when looking at the "intended()" function in the sendLoginResponse() one.

Collapse
 
luismir15 profile image
Luis Miranda

Hello Ariel, what version of Laravel would this example apply?

Collapse
 
arielmejiadev profile image
Ariel Mejia

Hi, the example was created with Laravel 7 using "laravel/ui" package, its an official package, with Laravel 8 you can still working with "laravel/ui" package or use Jetstream, that use "hooks" some method to override behavior without coverriding class methods directly, the example works perfectly on "laravel/ui", if you prefer jetstream go to official jetstream docs to get more info about it.