0
votes

I need to do an ACL check for the user before allowing access to the admin panel of a Laravel 5 website. What is the best way to do this for an entire controller group in the namespace App\Http\Controllers\Admin\*? Ultimately, I'm looking for a "set and forget" method to do this, and middleware looks like the best option so far.

The initial idea was to assign a middleware to the admin route, but this does not prevent any other non-admin route from accessing the controllers. This means a route can still target the admin controllers and bypass the ACL check.

The next idea was to insert the assignment in the constructor on the controllers, but this would require each additional controller to explicitly include the middleware. This would require a developer to know that the middleware should be included, which allows them to miss it entirely. This also applies to using one base controller as the parent for all admin controllers, since the developer would need to know that the base controller should be extended. Right now, this looks like the best solution.

This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin\*? Or, is there a better way for the ACL check to never need to be explicitly assigned to every admin controller?

2

2 Answers

3
votes

This leads us back to the question: can middleware be assigned to a controller wildcard namespace like App\Http\Controllers\Admin*?

No

The most simplest approach you can do is create a base controller such as App\Http\Controllers\Admin\Controller and include the middleware while all other App\Http\Controllers\Admin\* extends it.

Alternatively, while still adding App\Http\Controllers\Admin\Controller, you could instead inject the middleware through IoC Container.

App::afterResolving('App\Http\Controllers\Admin\Controller', function ($controller) {
    $controller->middleware('acl');
});
1
votes

EDIT

My previous answer didn't quite work for all situations; it broke a lot of other routes. Here's what I ended up doing instead (in app/Http/routes.php):

Route::group(['namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'App\Http\Middleware\Acl'], function()
{
  Route::get('/', 'AdminController@index');
  Route::get('/user', 'User\UserController@index');
  ...
});

This at least targets all admin controllers when I define a route. It's not exactly everything I had hope for, but it will do.