13

I'm trying to add a simple middleware to check if a user matches a role. I'm running into an issue when I use the middleware, I get an Exception:

ReflectionException: class role does not exist

I do not attempt to call a class named role so I assume this is happening magically in Laravel somewhere.

My middleware:

class RoleMiddleware
{
    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */
    public function handle($request, Closure $next, $role)
    {
        if (! $request->user()->is($role)) {
            return redirect('/login');
        }

        return $next($request);
    }

}

In the users table, I have a role field and in the User model I have:

/**
 * Check if a user is a certain role
 *
 * @param $role
 * @return bool
 */
function is($role) {
    return ($this->role == $role);
}

The route group:

Route::group(['prefix' => 'support', 'middleware' => ['role:admin', 'web']], function() {
        Route::get('threads', 'ThreadController@index');
});

In Http/Kernel.php:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ],

    'role' => [
        RoleMiddleware::class,
    ],
];

Anyone have any ideas on what could be causing this ReflectionException?

Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95
  • Try `\App\Http\Middleware\RoleMiddleware::class` and execut `dump-autoload` also, then tell us if it work. – Felippe Duarte May 16 '16 at 18:50
  • The namespace is fine, it can reach the class and it throws an error about the missing argument if I just use middleware 'role' instead of 'role:admin'. – Devon Bessemer May 16 '16 at 18:53

4 Answers4

24

For Spatie/Laravel-Permissions to work properly we have to register the two route middleware (role and permission) in app/Http/Kernel.php as follows, along with the other two auth middleware:

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
];
Randika Vishman
  • 7,983
  • 3
  • 57
  • 80
  • you can also now add `'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,` to `protected $routeMiddleware` – Scotty G Jul 12 '19 at 20:10
  • It is found [in the docs](https://docs.spatie.be/laravel-permission/v3/basic-usage/middleware/). – Pathros Apr 09 '20 at 03:47
4

In Http/Kernel.php, you need to include the full path to RoleMiddleware. E.g.:

...
'role' => [
    \App\Http\Middleware\RoleMiddleware::class,
],
...
Niraj Shah
  • 15,087
  • 3
  • 41
  • 60
3

Try to change this

Route::group(['prefix' => 'support', 'middleware' => ['role:admin', 'web']], function() {
    Route::get('threads', 'ThreadController@index');
});

to

Route::group(['prefix' => 'support', 'middlewareGroups' => ['role:admin', 'web']], function() {
    Route::get('threads', 'ThreadController@index');
});

I'm a beginner in laravel i was facing this same problem and fixed by changing the name from middleware to "your-own-middelware-name".

Vipertecpro
  • 3,056
  • 2
  • 24
  • 43
2

This came down to two problems:

  1. $middlewareGroups may not allow for parameters. (Needs to be confirmed) Dropping RoleMiddleware down to $routeMiddleware got rid of the exception.

  2. Having 'web' after 'role:admin' resulted in a null $request->user(). So for future users, you may need to consider placement of your middleware and a check to see if $request->user() is null.

Hope this helps someone else.

Randika Vishman
  • 7,983
  • 3
  • 57
  • 80
Devon Bessemer
  • 34,461
  • 9
  • 69
  • 95