Search code examples
laravel-5user-roleslaravel-middleware

How do I convert Laravel 4.2 beforeFilter in controller into custom middleware in Laravel 5.2


I'm in the process of upgrading a Laravel 4.2 app I inherited to Laravel 5.2. The app has multiple roles for logged in users that were handled with a before filter. Each controller has an array of functions and roles allowed for those functions:

public $actionFilter = [
    'directories-create'=>['super','tsr'],
    'directories-destroy'=>['super','tsr'],
    'directories-edit'=>['super','tsr'],
    'directories-directoryinfo'=>['super','tsr','admin'],
    'directories-index'=>['super','tsr'],
    'directories-store'=>['super','tsr'],
    'directories-update'=>['super','tsr'],
];

then in the construct function it calls two beforeFilters that were in Controller.php

public function __construct()
{
    $this->beforeFilter('@filterAuthorization');
    $this->beforeFilter('@rerouteSite');
}

Controller.php had a public function filterAuthorization that checked if user's role had access to the route, and a public function rerouteSite that allowed user to stay on the same page but switch between accounts (for example, for a support rep).

I've spent a fair amount of time reading the manual, Googling and reading various tutorials, but I'm still unclear how to get my route-role array connected to the auth middleware. The Laravel docs provide syntax but not the context and the examples I've read either take a different approach or have a different usecase from mine.

I tried leaving the filter functions in Controller.php and calling them like this in the construct:

public function __construct()
{
    $this->middleware('@filterAuthorization');
    $this->middleware('@rerouteSite');
}

I get an error message: "Class @filterAuthorization does not exist"

I tried putting those functions in app\Http\Middleware\Authenticate, but I get the same error message: "Class @filterAuthorization does not exist"

I followed the steps on Matt Stauffer's blog here (https://mattstauffer.com/blog/laravel-5.0-middleware-filter-style/) and here (https://mattstauffer.com/blog/passing-parameters-to-middleware-in-laravel-5.1/) and on Nwanze Franklin's post here (https://dev.to/franko4don/deep-dive-into-middlewares-in-laravel-doo) as follows.

Create two new middleware files with Artisan

php artisan make:middleware FilterAuthorization
php artisan make:middleware RerouteSite

Edit the new middleware files with the functions from the old Controller.php

Register the new middleware in App\Http\Kernel

protected $routeMiddleware = [
    'filterauth' => \Illuminate\Routing\Middleware\FilterAuthorization::class,
    'reroutesite' => \Illuminate\Routing\Middleware\RerouteSite::class,
];

Edit the public function __contstruct() in the Controllers than need filtering

public function __construct()
{
    $this->middleware('FilterAuthorization');
    $this->middleware('RerouteSite');
}

Run

composer dump-autoload
php artisan clear-compiled
php artisan optimize

and I still get the same error: Class FilterAuthorization does not exist

I'm sure there's a simple way to put this together without rewriting the whole role authorization system. Can someone point me in the right direction?


Solution

  • The kernel registration needs to reference the correct file locations as follows:

        'filterauth' => \App\Http\Middleware\FilterAuthorization::class,
        'reroutesite' => \App\Http\Middleware\RerouteSite::class,
    

    And the controller boot should use the aliases rather than the class names:

    public function __construct()
    {
        $this->middleware('filterauth');
        $this->middleware('reroutesite');
    }
    

    Then Laravel can find the custom middleware.