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

Airlock Laravel Package

laravel/airlock

Laravel Sanctum (formerly Airlock) provides a lightweight authentication system for Laravel SPAs and simple APIs, offering first-party SPA cookie auth plus API token issuing and management for users, mobile apps, and third-party clients.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/sanctum
    php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
    php artisan migrate
    
  2. Configure Middleware: Add Sanctum’s middleware to your app/Http/Kernel.php:

    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    
  3. First Use Case:

    • SPA Authentication:
      // Login endpoint
      public function login(Request $request) {
          $request->validate(['email' => 'required|email', 'password' => 'required']);
          $user = User::where('email', $request->email)->first();
          if (!$user || !Hash::check($request->password, $user->password)) {
              return response()->json(['message' => 'Unauthorized'], 401);
          }
          return response()->json([
              'token' => $user->createToken('api-token')->plainTextToken,
              'user' => $user
          ]);
      }
      
    • API Route Protection:
      Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
          return $request->user();
      });
      

Key Files to Review

  • config/sanctum.php: Configure stateful domains, token expiration, and middleware.
  • app/Models/User.php: Ensure the HasApiTokens trait is added.
  • routes/api.php: Define Sanctum-protected routes.

Implementation Patterns

Common Workflows

1. Token Management

  • Create Tokens:
    $token = $user->createToken('mobile-app-token');
    $token->plainTextToken; // Raw token (use once, then revoke)
    
  • Revoke Tokens:
    $user->tokens()->where('name', 'mobile-app-token')->delete();
    
  • Check Token Scopes:
    $token = $user->currentAccessToken();
    $token->scopes; // ['read', 'write']
    

2. Stateful API for SPAs

  • Configure Stateful Domains:
    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')),
    
  • CSRF Protection: Sanctum automatically handles CSRF tokens for stateful requests via cookies. Ensure your frontend sends the X-XSRF-TOKEN header.

3. Custom Token Logic

  • Extend HasApiTokens:
    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable {
        use HasApiTokens;
    
        public function createCustomToken($name) {
            return $this->createToken($name)->tap(function ($token) {
                $token->scopes = ['custom-scope'];
            });
        }
    }
    
  • Override Token Retrieval:
    Sanctum::getAccessTokenFromRequestUsing(function ($request) {
        return $request->bearerToken() ?: $request->cookie('sanctum');
    });
    

4. Multi-Guard Support

  • Configure Guards:
    'guards' => [
        'api' => ['driver' => 'sanctum', 'provider' => 'users'],
        'admin-api' => ['driver' => 'sanctum', 'provider' => 'admins'],
    ],
    
  • Use Guards in Routes:
    Route::middleware('auth:admin-api')->get('/admin', function () {
        return auth()->user();
    });
    

5. Token Expiration and Tracking

  • Enable last_used_at:
    'tokens' => [
        'prune' => true,
        'expire' => true,
        'last_used_at' => true, // Track token usage time
    ],
    
  • Prune Expired Tokens: Sanctum automatically prunes expired tokens during boot. Manually trigger:
    php artisan sanctum:prune
    

Integration Tips

Frontend Integration (React/Vue)

  • Login Flow:
    // Fetch token from Laravel
    const response = await fetch('/api/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
    });
    const { token } = await response.json();
    
    // Set token and CSRF cookie
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
    document.cookie = `XSRF-TOKEN=${response.headers['x-xsrf-token']}; path=/`;
    

Testing

  • Mock Auth:
    $user = User::factory()->create();
    Sanctum::actingAs($user, ['read', 'write']);
    
  • Test Stateful Requests:
    $response = $this->actingAs($user)
        ->withHeaders(['Accept' => 'application/json'])
        ->post('/api/stateful-endpoint');
    

Performance

  • Index Tokens Table: Sanctum adds indexes to personal_access_tokens by default (since v4.2.0). For large-scale apps, ensure your database is optimized:
    -- Example for PostgreSQL
    CREATE INDEX idx_personal_access_tokens_user_id ON personal_access_tokens(user_id);
    

Gotchas and Tips

Pitfalls

1. Token Validation Failures

  • Issue: 401 Unauthorized despite valid token.
  • Debugging:
    • Verify the token is sent in the Authorization: Bearer <token> header.
    • Check if the token exists in the database and isn’t expired.
    • Ensure the sanctum middleware is applied to the route.
  • Fix:
    // Temporarily disable token validation for debugging
    Sanctum::ignoreMissingToken();
    

2. CSRF Token Mismatch

  • Issue: 419 Page Expired for stateful requests.
  • Debugging:
    • Ensure the frontend sends the X-XSRF-TOKEN header with the CSRF cookie value.
    • Check if SameSite cookie attributes are misconfigured (e.g., SameSite=Lax may cause issues in some setups).
  • Fix:
    // In config/sanctum.php
    'encrypt_cookies' => false, // Disable if using HTTPS
    

3. Token Not Found

  • Issue: TokenNotProvidedException or TokenMismatchException.
  • Debugging:
    • Confirm the token is being passed correctly (check request headers/cookies).
    • Verify the token hasn’t been revoked or expired.
    • Ensure the getAccessTokenFromRequestUsing method isn’t overriding default behavior unintentionally.
  • Fix:
    // Custom token retrieval logic
    Sanctum::getAccessTokenFromRequestUsing(function ($request) {
        return optional($request->user())->currentAccessToken()?->token;
    });
    

4. Stateful Domain Misconfiguration

  • Issue: Stateful requests failing with 403 Forbidden.
  • Debugging:
    • Verify SANCTUM_STATEFUL_DOMAINS includes all frontend domains (e.g., localhost,myapp.test,api.myapp.com).
    • Check if the request’s Origin or Referer header matches a stateful domain.
  • Fix:
    // Allow same-domain requests to be stateful
    'stateful' => [
        'localhost',
        '127.0.0.1',
        'myapp.test',
        '*.myapp.com',
    ],
    

5. Token Expiration Edge Cases

  • Issue: Tokens expiring unexpectedly.
  • Debugging:
    • Check config/sanctum.php for expire and token_ttl settings.
    • Ensure last_used_at is enabled if tracking token usage.
  • Fix:
    // Extend token TTL (in minutes)
    'tokens' => [
        'expire' => true,
        'token_ttl' => 1440, // 24 hours
    ],
    

Debugging Tips

1. Log Token Events

  • Override the PersonalAccessToken model to log events:
    class PersonalAccessToken extends \Laravel\Sanctum\PersonalAccessToken {
        protected static function booted() {
            static::created(function ($token) {
                Log::info('Token created', ['token' => $token->token]);
            });
            static::deleted(function ($token) {
                Log::info
    
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai