laravel 5 middleware with parameters

4.7k views Asked by At

I'm an absolute beginner in Laravel 5.

I've created a middleware class called BeforeMiddleware the blueprint of that class is below.

class BeforeMiddleware {
    public function handle($request, Closure $next, $role)
    {
        if($request->user()->hasRole($role)){
            return redirect('/pensions');
        }
        return $next($request);
    }
}

registered in kernel.php as

protected $routeMiddleware = [
        'auth' => 'App\Http\Middleware\Authenticate',
        'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
        'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
        'role' => 'App\Http\Middleware\BeforeMiddleware',
    ];

User model is below

class User extends Model {
    public function hasRole($name)
    {
        return ($this->role->name == $name) ? true : false;
    }

    public function role()
    {
        return $this->belongsTo('App\Models\Role');
    }
}

and usage in routes.php is below.

Route:get('/reporting', [ 'middleware' => 'role:Owner', 'uses' => function(){
    return 'secret data only be viewable by the owners';
}]);

If I open that in the browser /reporting I get the following error.

ReflectionException in Container.php line 776:
Class role:Owner does not exist

HOWEVER if I hard code 'Owner' in middleware and remove the $role parameter and also removed it from routes which now looks like this.

BeforeMiddleware.php

class BeforeMiddleware {
    public function handle($request, Closure $next, $role)
    {
        if($request->user()->hasRole('Owner')){
            return redirect('/pensions');
        }
        return $next($request);
    }
}

routes.php

Route:get('/reporting', [ 'middleware' => 'role', 'uses' => function(){
        return 'secret data only be viewable by the owners';
    }]);

it works as desired...

therefore my question is how to pass that parameter when using middleware to control routes

Any Idea?

2

There are 2 answers

1
Jake Opena On

Since you are using Laravel 5.0, I suggest to just create separate middlewares for your roles.

Kernel.php

'owner' => 'App\Http\Middleware\OwnerMiddleware',

OwnerMiddleware

public function handle($request, Closure $next)
{
    if($request->user()->hasRole('Owner')){
        return redirect('/pensions');
    }
    return $next($request);
}

Then in routes.php

Route:get('/reporting', [ 'middleware' => 'owner', 'uses' => function(){
    return 'secret data only be viewable by the owners';
}]);
2
Sh1d0w On

If you read carefully the Middleware Documentation, you will notice this line

Middleware parameters may be specified when defining the route by separating the middleware name and parameters with a :. Multiple parameters should be delimited by commas

So in your case if your middleware class is called BeforeMiddleware, the first part of middleware definition should be before then :, and after that you can define your route parameters, separated with comma, like this:

Route:get('/reporting', [ 'middleware' => 'before:Owner', 'uses' => function(){
    return 'secret data only be viewable by the owners';
}]);