squash migrations — schema:dump for large projects
Intermediate5 min read·lv-14-010
sql
Concept
Laravel Passport provides a full OAuth2 server implementation for Laravel applications. It's appropriate when you need the full OAuth2 flow — issuing access tokens to third-party applications, supporting authorization code grants for external developers, or building a platform where users authorize external apps to access their data.
OAuth2 grants supported by Passport:
- Authorization Code: The full OAuth2 flow. User is redirected to your server to authorize. Third-party apps get a code they exchange for a token. Standard flow for "Login with Our App" integrations.
- Password grant (deprecated in OAuth2.1): Username/password directly. Only for first-party clients. Avoid for new projects — use Sanctum instead.
- Client Credentials: Machine-to-machine. No user involved. Server-to-server API access.
- Personal Access Tokens: Users manually generate tokens from a dashboard. Like GitHub personal access tokens.
Passport vs Sanctum:
- Sanctum: Simple API tokens and SPA cookie-based auth. No OAuth2 server. 90% of Laravel APIs should use Sanctum.
- Passport: Full OAuth2 server. Use when external developers will integrate with your API, or when you need the authorization code flow.
Installation: composer require laravel/passport, php artisan install:api --passport, generates encryption keys, registers routes.
Code Example
php
<?php
// Installation
// composer require laravel/passport
// php artisan install:api --passport
// php artisan passport:keys (generates OAuth keys in storage/)
// User model must use HasApiTokens from Passport
use Laravel\Passport\HasApiTokens;
class User extends \Illuminate\Foundation\Auth\User
{
use HasApiTokens, \Illuminate\Database\Eloquent\Factories\HasFactory;
}
// config/auth.php — set API guard to Passport
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
// Client credentials grant — machine-to-machine
// Register a client: php artisan passport:client --client
// In routes/api.php:
Route::middleware('client')->group(function() {
Route::get('/server-to-server-data', function() {
return response()->json(['data' => '...']);
});
});
// Personal access tokens — users generate their own
$user = User::find(1);
$token = $user->createToken('MyApp Token', ['read-orders', 'write-orders']);
$accessToken = $token->accessToken; // JWT string to store and use
// Route protection with scopes
Route::middleware(['auth:api', 'scopes:read-orders'])->group(function() {
Route::get('/orders', [OrderController::class, 'index']);
});
// Authorization Code flow — routes auto-registered by Passport
// GET /oauth/authorize — show authorization page
// POST /oauth/authorize — user approves
// POST /oauth/token — exchange code for token
// POST /oauth/token — refresh access token
// Introspecting current token in controller
$token = $request->user()->token(); // current token
$scopes = $token->scopes; // array of granted scopes
$request->user()->tokenCan('read-orders'); // check scope