Redirect if authenticated logic in Laravel's built-in auth?

26,009

Solution 1

You are not using the middleware correctly. This piece of code will fire everytime you send a request when you are logged in.

To change the redirect location after login you can override the redirectPath() method in your AuthController. (You can find the original method in vendor/laravel/framework/src/Illuminate/Foundation/Auth/RedirectsUsers.php)

This would look something like this:

...

public class AuthController extends Controller {

    ...

    public function redirectPath()
    {
        if(Auth::user()->sign_up_complete == 1) {
            return '/';
        } else {
            if(Auth::user()->step_one_complete == 0) {
                return '/register/step-1';
            } elseif(Auth::user()->step_two_complete == 0) {
                return '/register/step-2';
            } else {
                return '/';
            }
        }
    }


    // The rest of the class implementation.

}

Note: I've replaced the $this->auth() method with the Facade alternative (Auth::). Just because I am not sure if the AuthController has an auth() method.

Solution 2

High level answer: the purpose of RedirectIfAuthenticated is to keep an already authenticated user from reaching the login or registration routes/views since they're already logged in.

Test: bookmark the login view. Then login. Close the browser or window. Open the login bookmark. You'll go straight to user's home or where ever specified in RedirectIfAuthenticated.

For purposes of the LoginController, create a redirecTo() method, which is what the redirectPath() method looks for to see if you have customized the redirect.

// example
public function redirectTo()
{
    switch (auth()->user()->role) {
        case 'foo':
            return route('foo.home');

        case 'bar':
            return route('bar.home');

        default:
            auth()->logout();
            return route('web.welcome');
    }
}

Solution 3

To understand why your routing logic is never reached, you should look in app/Http/Kernel.php where the RedirectIfAuthenticated middleware is registered:

protected $routeMiddleware = [
    ...
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    ...
];

This means if a user navigates to a route that is not protected by the guest route middleware, the request never passes through the RedirectIfAuthenticated class and so misses your logic completely.

You can add guest middleware to your registration routes in your routes file to force the routing to pass through your code like this:

Route::get('/register/step-1', '<YOUR CONTROLLER METHOD>')->middleware('guest');

But, since you say the user is already logged in (not a guest) you should instead move your code as suggested by the other answers.

Only adding this as an answer, because it couldn't be clarified in the space allowed by a comment.

Solution 4

Solution is in Mark Walet's answer, but need little correction. Return should be a string:

public class AuthController extends Controller {

    ...

    public function redirectPath()
    {
        if(Auth::user()->sign_up_complete == 1) {
            return '/';
        } else {
            if(Auth::user()->step_one_complete == 0) {
                return '/register/step-1';
            } elseif(Auth::user()->step_two_complete == 0) {
                return '/register/step-2';
            } else {
                return '/';
            }
        }
    }


    // The rest of the class implementation.

}

Solution 5

u cant change the core files of laravel all u need to do is adding this code to Auth\AuthController

protected $redirectPath = '/dashboard';
Share:
26,009
Mike
Author by

Mike

Technical Director for Reckless, a digital agency in the UK and Europe.

Updated on March 02, 2020

Comments

  • Mike
    Mike over 4 years

    This question has been asked before, and I believe my code to be correct, but I am getting strange behaviour.

    I need to redirect the user to different routes after login depending on some database values. I thought that in order to do this I simply had to place my logic in the handle method of app/Http/Middleware/RedirectIfAuthenticated.php. My method currently looks like so:

    public function handle($request, Closure $next)
    {
    
        if ($this->auth->check()) {
            if($this->auth->user()->sign_up_complete == 1){
                return redirect('/');
            } else {
                if($this->auth->user()->step_one_complete == 0){
                    return redirect('/register/step-1');
                } elseif($this->auth->user()->step_two_complete == 0){
                    return redirect('/register/step-2');
                } else {
                    return redirect('/');
                }
            }
        }
    
        return $next($request);
    }
    

    This does not work, and upon login the user is redirected to /home. I have tried placing dd($this->auth->user()) inside the $this->auth->check() condition, but it never gets run. If I place it outside of that check then it's run on every request. It looks like $this->auth->check() is never run.

    My question: If not here, where should this logic go?

    I have removed protected $redirectTo = '/account'; from the AuthController.php controller too.

  • Mark Walet
    Mark Walet over 6 years
    This should be something you say in a comment in my solution. Then I got a notification and updated it right away.
  • Dmitry
    Dmitry over 6 years
    oh.. ok, sorry. Will do like this next time