laravel/passport
Laravel Passport provides an OAuth2 server for Laravel, enabling API authentication with personal access tokens, password and authorization code grants, and client credentials. Integrates with Laravel’s auth system for secure, standards-based token issuing.
Installation:
composer require laravel/passport
php artisan passport:install
This runs migrations, creates keys, and registers the Passport service provider.
Configure Auth Guard:
In AuthServiceProvider, ensure Passport is configured for your auth guard (e.g., users):
Passport::routes();
Passport::hashClientSecrets();
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));
Passport::enableImplicitGrant();
First Use Case:
Passport::actingAs() helper in tests or manually:
$user = User::find(1);
$token = $user->createToken('API Token')->accessToken;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
database/migrations/ for oauth_* tables.app/Http/Middleware/ for AuthenticateWithPassport.Passport::actingAs(), Passport::actingAsClient() for testing.Token Issuance:
createToken() on a User model.
$token = $user->createToken('App Access')->accessToken;
Passport::actingAsClient() for machine-to-machine auth.
$client = Client::find(1);
$token = Passport::actingAsClient($client)->createToken()->accessToken;
Route Protection:
auth:api middleware to routes or groups:
Route::middleware(['auth:api', 'throttle:60,1'])->group(function () {
// Protected routes
});
Scopes and Permissions:
$token = $user->createToken('Admin Access', ['admin', 'write'])->accessToken;
public function handle($request, Closure $next, $scope) {
if (!$request->user()->tokenCan($scope)) {
abort(403);
}
return $next($request);
}
Token Revocation:
Token model:
$user->tokens()->delete(); // Revoke all user tokens
$token->revoke(); // Revoke a specific token
Customizing Responses:
Passport::tokensCanUseManyScopes();
Passport::tokensExpireIn(CarbonInterval::hours(1));
Testing:
Use Passport::actingAs() for authenticated tests:
$response = $this->actingAs($user)->get('/api/user');
For client credentials:
$response = $this->actingAsClient($client)->post('/oauth/token', [
'grant_type' => 'client_credentials',
]);
Third-Party Clients:
Register clients via the Client model or use the Passport::client() helper:
$client = Passport::client(
'client-id',
'client-secret',
['password', 'refresh_token']
);
Custom Guards:
Extend TokenGuard for non-standard auth logic:
class CustomTokenGuard extends TokenGuard {
public function getUser() {
// Custom user resolution logic
}
}
Event Listeners:
Listen to token events (e.g., Passport::events()):
Passport::tokensUsingManyScopes(function ($user, $token) {
// Custom logic when token uses multiple scopes
});
UUID vs. Integers:
Schema::table('oauth_clients', function (Blueprint $table) {
$table->string('id')->change();
});
Client Secret Hashing:
Token Guard Configuration:
AuthServiceProvider configures the correct guard:
Passport::useTokenGuard('api'); // Explicitly set guard name
Scope Validation:
tokenCan():
if (!$request->user()->tokenCan('WRITE')) { // Fails if scope is 'write'
abort(403);
}
Refresh Tokens:
Passport::refreshTokensExpireIn(null); // Disable expiration
Middleware Order:
auth:api after throttle middleware to avoid throttling unauthenticated requests.Headless Mode:
Passport::ignoreRoutes(); // Disable built-in routes
Token Issues:
$token = \Laravel\Passport\Client::find(1)->findToken($request->bearerToken());
dd($request->user()->token()->scopes);
Client Misconfiguration:
oauth_clients table.CORS Errors:
Access-Control-Allow-Origin headers are set for OAuth endpoints:
Passport::enableImplicitGrant();
Passport::tokensCanUseManyScopes();
Database Locks:
DB::transaction(function () {
$user->tokens()->delete();
});
Custom Token Models:
Laravel\Passport\Token or Laravel\Passport\Client:
class CustomToken extends Token {
public function customMethod() { ... }
}
AuthServiceProvider:
Passport::tokensUsingManyScopes(function ($user, $token) {
return new CustomToken($token->getKey());
});
Custom Grant Types:
Laravel\Passport\Bridge\Grant:
class CustomGrant implements Grant {
public function respondToAccessRequest() { ... }
}
Passport::grantsUsing():
Passport::grantsUsing([CustomGrant::class]);
Custom User Resolution:
findForPassport() in your User model:
public static function findForPassport($identifier) {
return static::where('email', $identifier)->first();
}
Token Lifecycle Hooks:
passport.token.created or passport.token.revoked events:
event(new Passport\Events\TokenCreated($token));
Custom Error Responses:
OAuthServerException rendering:
Passport::registerExceptionRenderer(function ($request, \League\OAuth2\Server\Exception\OAuthServerException $exception) {
return response()->json(['error' => $exception->getMessage()], 400);
});
Trusted Proxies:
Passport::trustedProxies(['192.168.1.0/24']);
Key File Permissions:
bootstrap/cache/passport-*.pem files are readable by the web server:
chmod 644 bootstrap/cache/passport-*.pem
Personal Access Tokens (PAT):
Passport::
How can I help you explore Laravel packages today?