Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Passport Laravel Package

laravel/passport

Laravel Passport provides a full OAuth2 server for Laravel, enabling API authentication with access tokens, personal access tokens, and client credentials. Includes token issuing, revocation, and scope support with first-party integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/passport
    php artisan passport:install
    
    • Runs migrations, creates OAuth tables, and generates encryption keys.
    • Critical: Always run php artisan passport:keys --force in production to regenerate keys.
  2. User Model: Ensure your User model uses HasApiTokens trait and implements OAuthenticatable:

    use Laravel\Passport\HasApiTokens;
    use Laravel\Passport\Contracts\OAuthenticatable;
    
    class User extends Authenticatable implements OAuthenticatable
    {
        use HasApiTokens;
        // ...
    }
    
  3. First API Request: Use Passport::actingAs() in tests or manually issue tokens via:

    php artisan passport:client --password
    
    • Store the generated client_id and client_secret for OAuth flows.

First Use Case: Password Grant Flow

  1. Route Setup:

    Route::post('/oauth/token', function () {
        return Passport::issueToken('password', request()->all());
    });
    
  2. Client Request:

    curl -X POST http://your-app.test/oauth/token \
      -d "grant_type=password" \
      -d "client_id=YOUR_CLIENT_ID" \
      -d "client_secret=YOUR_CLIENT_SECRET" \
      -d "username=user@example.com" \
      -d "password=password" \
      -d "scope=read"
    
  3. Token Usage:

    $response = Http::withHeaders([
        'Authorization' => 'Bearer ' . $token,
    ])->get('/api/resource');
    

Implementation Patterns

Core Workflows

1. Token Issuance

  • Password Grant (for user credentials):
    $token = Passport::issueToken('password', [
        'grant_type' => 'password',
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'username' => $user->email,
        'password' => $password,
        'scope' => 'read write',
    ]);
    
  • Client Credentials (for machine-to-machine):
    $token = Passport::issueToken('client_credentials', [
        'grant_type' => 'client_credentials',
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'scope' => 'api',
    ]);
    
  • Authorization Code (for web apps):
    // Redirect user to OAuth auth endpoint
    return redirect()->route('passport.authorizations.create');
    
    // Exchange code for token
    $token = Passport::issueToken('authorization_code', [
        'grant_type' => 'authorization_code',
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'code' => $authorizationCode,
        'redirect_uri' => 'https://your-app.com/callback',
    ]);
    

2. Token Validation & Middleware

  • API Routes:
    Route::middleware('auth:api')->get('/user', function (Request $request) {
        return $request->user();
    });
    
  • Custom Scopes:
    Route::middleware(['auth:api', 'scope:admin'])->get('/admin');
    
  • Client-Specific Middleware:
    Route::middleware(['auth:api', 'client:mobile-app'])->get('/mobile');
    

3. Personal Access Tokens (PATs)

  • Create via Tinker:
    $user = App\Models\User::find(1);
    $token = $user->createToken('My PAT')->accessToken;
    
  • Revoke:
    $user->tokens()->delete();
    

4. Testing

  • Mock Auth:
    $user = User::factory()->create();
    Passport::actingAs($user, ['read', 'write']);
    
    $response = $this->getJson('/api/resource');
    $response->assertOk();
    
  • Client Credentials:
    $client = Passport::personalAccessClients()->create([
        'name' => 'Test Client',
        'password_client' => true,
    ]);
    Passport::actingAsClient($client, ['api']);
    

Integration Tips

1. Scopes & Policies

  • Define scopes in AuthServiceProvider:
    Passport::tokensCan([
        'read' => 'Read access',
        'write' => 'Write access',
    ]);
    
  • Use policies for granular control:
    class PostPolicy {
        public function update(User $user, Post $post) {
            return $user->can('write');
        }
    }
    

2. Customizing Responses

  • Override error responses:
    Passport::tokensExpireIn(CarbonInterval::minutes(60));
    Passport::refreshTokensExpireIn(CarbonInterval::days(30));
    Passport::personalAccessTokensExpireIn(never());
    

3. Rate Limiting

  • Combine with Laravel's rate limiting:
    Route::middleware(['throttle:60,1', 'auth:api'])->get('/api/resource');
    

4. Multi-Tenant Support

  • Use actingAs with tenant context:
    $tenant = Tenant::find($request->tenant_id);
    Passport::actingAs($user, [], $tenant->id);
    

5. Token Storage

  • Extend AccessToken model to add custom fields:
    class AccessToken extends Laravel\Passport\AccessToken {
        protected $casts = [
            'metadata' => 'json',
        ];
    }
    

Gotchas and Tips

Pitfalls

1. Key Management

  • Never commit bootstrap/cache/passport-public.key or passport-private.key to version control.
  • Regenerate keys in production after deployment:
    php artisan passport:keys --force
    
    • This invalidates all existing tokens. Plan downtime or use a rolling update.

2. Token Lifecycle

  • Client Credentials Tokens now have a dedicated lifetime (configurable via Passport::clientCredentialsTokensExpireIn()).
  • PATs are no longer confidential by default (v13+). Use password_client for confidential clients:
    $client = Passport::personalAccessClients()->create([
        'name' => 'Confidential Client',
        'password_client' => true, // Forces confidentiality
    ]);
    

3. User ID Collisions

  • Avoid using integer IDs for both users and clients if they overlap (e.g., user ID 5 and client ID 5).
    • Fix: Use UUIDs for clients or customize the findForPassport method:
      public function findForPassport($identifier) {
          return $this->where('id', $identifier)->orWhere('email', $identifier)->first();
      }
      

4. Middleware Order

  • auth:api must come before scope or client middleware:
    // Correct
    Route::middleware(['auth:api', 'scope:admin'])->get('/admin');
    
    // Incorrect (will fail silently)
    Route::middleware(['scope:admin', 'auth:api'])->get('/admin');
    

5. Token Guard Configuration

  • Ensure TokenGuard is properly configured in AuthServiceProvider:
    Passport::tokensCan([...]);
    Passport::hashClientSecrets();
    Passport::routes(); // Only if using built-in auth routes
    

Debugging Tips

1. Token Issues

  • Check token validity:
    php artisan passport:tokens
    
  • Revoke all tokens for a user:
    $user->tokens()->delete();
    
  • Log token events (enable in config/auth.php):
    'passport' => [
        'log_events' => true,
    ],
    

2. Common Errors

Error Solution
invalid_grant Check client_id, client_secret, or user credentials.
unsupported_grant_type Verify the grant type (e.g., password, client_credentials).
invalid_scope Ensure scopes are defined in tokensCan() and requested in the grant.
invalid_client Regenerate client secrets or check password_client flag.
invalid_request Validate all required fields (e.g., redirect_uri for authorization code).

3. Performance

  • Avoid N+1 queries when eager-loading tokens:
    $user->load('tokens'); //
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata