Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

amcardwell's avatar

Laravel 5.4: Bind AuthServiceProvider to route group?

My routes are split up into 2 groups: the web(default) group and the admin(custom) group. The admin group uses the auth middleware. Everything else uses the web middleware.

I'm having an issue where my AuthServiceProvider is querying my Permissions model in both groups... but I only want to query my Permissions model when a user requests access to a route within my admin group. Here is my AuthServiceProvider:

    <?php

    namespace App\Providers;

    use App\Models\Permission;
    use Illuminate\Support\Facades\Gate;
    use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

    class AuthServiceProvider extends ServiceProvider
    {
     /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy'
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Gate::before( function($user){
            if($user->isAdmin()){
                return true;
            }
        });

        foreach ($this->getPermissions() as $permission) {
            Gate::define($permission->name, function ($user) use ($permission) {
                return $user->hasRole($permission->roles);
            });
        }
    }

    protected function getPermissions()
    {
        return Permission::with('roles')->get();
    }

So in every request within my web middleware, my app is querying permissions for a user when it doesnt need to. There is no need for any permissions to get queried within my web middleware. So how do I tell my AuthServiceProvider to check permissions for only routes within my Auth group (or middleware)?

Debugbar query screengrab:

Debugbar events screengrab:

0 likes
4 replies
Snapey's avatar

what does your web.php look like?.

isn't it the case that all service providers are booted on every request? I can't remember specifics but there is some way to indicate deferring the boot until the provider is needed?

Screenbeetle's avatar
Level 15

I can't suss a way to fix your issue but I can offer an alternative approach.

I would personally set up role/permissions checking logic in its own middleware. So something like 'checkRole.php' :

public function handle($request, Closure $next, $role)
    {
         // get and check permissions logic
         // and either 
                return $next($request);
         // or
                return redirect('login');
    }

You then need to make that middleware available to your app in kernal.php - under the $routeMiddleware section like so:

protected $routeMiddleware = [
       ..... other middleware
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'role' =>  \App\Http\Middleware\CheckRole::class,
    ];

after that you can query that middleware with parameters in your routes. Or bind it to a route file such as your admin.php. To do that you would add the binding in your RouteServiceProvider.php - something like:

protected function mapAdminRoutes()
    {
        Route::group([
            'middleware' => ['web', 'role:admin' ], //check role is admin
            'prefix' => 'admin',
            'namespace' => $this->namespace,
        ], function ($router) {
            require base_path('routes/admin.php');
        });
    }

Hope that helps in some way

amcardwell's avatar

@Screenbeetle Nice. That seemed to work! I just moved my logic into a new middleware. I was worried though that my defined Gate methods wouldnt apply but they did. Thanks again!

Please or to participate in this conversation.