Search code examples
phplaravel-routinglaravel-5.3laravel-authorization

Laravel 5.3 routes one url 2 controllers middleware


I am trying to use a differt controller for authorized users(middleware auth) and guests(middleware guest) with the same URI but I can't get it to work in laravel 5.3.

I tried making 2 routes with the same URI and differt middleware, but it isn't possible to create 2 routes with the same URI.

I tried a lot of things but in laravel 5.3 I can't use Auth::check() in the routes file, it will always return false:

Route::get('/', [
    'as' => 'home', 
    'uses' => (Auth::check() ? 'User\DashboardController' : 'Guest\HomeController'),
]);

I also tried to use a function in the route:

Route::get('/', [
    'as' => 'home', 
    'uses' => function (){
        $app = app();
        if(Auth::check()){
            $controller = $app->make('App\Http\Controllers\User\DashboardController'); 
            return $controller->callAction('getIndex', $parameters = []);
        }else{
            $controller = $app->make('App\Http\Controllers\Guest\HomeController');
            return $controller->callAction('getIndex', $parameters = []);
        }
    }
]);

Now the Auth::check() does mostly work, but now the middleware in the controllers __construct function gets ignored. And this doesn't look very nice.

I also have the problem when I redirect from the login to this route Auth::check() returns false. But if I refresh the page it returns true.

I do not want to use 1 controller and handle both the user and the guest in that controller, this is because my user controller extends another class than my guest controller.

Does someone know how I can have 1 route with a controller for guests and a differt controller for authorized users?


Solution

  • You can create new middleware:

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class isGuest
    {
        public function handle($request, Closure $next)
        {
            if (! \Auth::check()) {
                return redirect('/guest-page');
            }
    
            return $next($request);
        }
    }
    

    Then you need to register the new middleware in the app/Http/Kernel.php

    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
    

    And then just attach it to the needed routes:

        Route::get('user', [
            'uses' => 'UsersController@index',
            'as' => 'users.index'
        ])->middleware('isGuest');
    

    You can also use several middleware for one route:

      Route::get('user', [
            'uses' => 'UsersController@index',
            'as' => 'users.index'
        ])->middleware('isGuest', 'secondMiddleware' ...);
    

    More information here: https://laravel.com/docs/5.3/middleware#global-middleware