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/