Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can I use middleware to enforce role-based access control in Laravel Passport


Can I use middleware to enforce role-based access control in Laravel Passport


Yes, you can use middleware to enforce role-based access control in Laravel Passport. Here are the steps to achieve this:

1. Install Passport and Laravel Sanctum

- Install Passport and Laravel Sanctum to manage client permissions and roles:
bash
     composer require laravel/passport
     composer require laravel/sanctum
     

2. Extend the Client Model

- Extend the `Client` model to include roles and permissions:
php
     namespace App\Models;

     use Illuminate\Database\Eloquent\Factories\HasFactory;
     use Illuminate\Foundation\Auth\User as Authenticatable;
     use Illuminate\Notifications\Notifiable;
     use Laravel\Passport\Client as BaseClient;
     use Spatie\Permission\Traits\HasRoles;

     class Client extends BaseClient
     {
         use HasRoles;

         public $guard_name = 'api';
     }
     

3. Configure the Client Model

- Update the `AuthServiceProvider` to use the extended `Client` model:
php
     namespace App\Providers;

     use Illuminate\Support\Facades\Gate;
     use Illuminate\Support\Facades\Permission;
     use Laravel\Passport\Passport;
     use Spatie\Permission\PermissionRegistrar;

     class AuthServiceProvider extends ServiceProvider
     {
         public function boot()
         {
             Passport::useClientModel(\App\Models\Client::class);
         }
     }
     

4. Middleware Configuration

- Create a middleware to check the client's roles and permissions:
php
     namespace App\Http\Middleware;

     use Closure;
     use Illuminate\Support\Facades\Auth;

     class CheckRole
     {
         public function handle(Request $request, Closure $next)
         {
             if (!Auth::check()) {
                 return $next($request);
             }

             if (!Auth::user()->hasRole('admin')) {
                 return response()->json(['error' => 'Unauthorized'], 401);
             }

             return $next($request);
         }
     }
     

5. Use the Middleware

- Use the middleware in your routes:
php
     Route::middleware(['auth:api', 'check-role'])->group(function () {
         // Your API routes here
     });
     

Example Usage

Here is an example of how to use the client credentials grant to authenticate a machine-to-machine application and check the client's roles and permissions:

1. Create a Client:

bash
   php artisan passport:client
   

2. Get the Client ID and Secret:

php
   $clientSecret = $client->secret;
   $clientId = $client->id;
   

3. Authenticate with the API:

php
   $response = Http::asForm()->post('https://passport-app.test/oauth/token', [
       'grant_type' => 'client_credentials',
       'client_id' => $clientId,
       'client_secret' => $clientSecret,
       'scope' => 'your-scope',
   ]);
   $accessToken = $response->json()['access_token'];
   

4. Check Roles and Permissions:

php
   $response = Http::asForm()->get('https://passport-app.test/api/protected', [
       'Authorization' => 'Bearer ' . $accessToken,
   ]);
   if ($response->status() == 401) {
       return response()->json(['error' => 'Unauthorized'], 401);
   }
   

By following these steps, you can manage client permissions and roles in Laravel Passport and use them to authenticate machine-to-machine applications with your API.

Citations:
[1] https://stackoverflow.com/questions/49209754/laravel-passport-add-scopes-based-on-the-role-of-the-user
[2] https://laracasts.com/discuss/channels/general-discussion/roles-permissions-and-scopes-laravel-passport
[3] https://www.reddit.com/r/laravel/comments/ylik2h/user_permissions_with_laravel_passport/
[4] https://spatie.be/docs/laravel-permission/v6/basic-usage/passport
[5] https://wpwebinfotech.com/blog/laravel-passport/