0

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