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

Php Jwt Laravel Package

firebase/php-jwt

Encode and decode JSON Web Tokens (JWT) in PHP (RFC 7519). Supports common signing algorithms, header handling, and clock-skew leeway. Simple API with JWT::encode() and JWT::decode() plus Key objects for verification.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require firebase/php-jwt
    

    For environments without libsodium, add:

    composer require paragonie/sodium_compat
    
  2. First Use Case: Encode a JWT with a symmetric key (e.g., HS256):

    use Firebase\JWT\JWT;
    
    $key = 'your-secret-key';
    $payload = ['user_id' => 123, 'iat' => time()];
    $jwt = JWT::encode($payload, $key, 'HS256');
    

    Decode it in a Laravel middleware or controller:

    try {
        $decoded = JWT::decode($jwt, new \Firebase\JWT\Key($key, 'HS256'));
        $userId = $decoded->user_id;
    } catch (\Firebase\JWT\ExpiredException $e) {
        // Handle expired token
    }
    
  3. Where to Look First:


Implementation Patterns

1. Token Generation Workflow

  • Laravel Service Provider: Bind a JWTGenerator facade to centralize token creation:

    // app/Providers/JWTServiceProvider.php
    public function register()
    {
        $this->app->singleton('jwt', function () {
            return new class {
                public function generate(array $payload, string $key, string $algorithm = 'HS256')
                {
                    return JWT::encode($payload, $key, $algorithm);
                }
            };
        });
    }
    

    Usage:

    $token = app('jwt')->generate(['user_id' => 1], config('jwt.secret'));
    
  • Payload Standardization: Always include:

    $payload = [
        'iss' => 'your-app-name', // Issuer
        'aud' => 'your-api',      // Audience
        'iat' => time(),          // Issued at
        'exp' => time() + 3600,   // Expires in 1 hour
        'data' => [...]           // Custom claims
    ];
    

2. Authentication Middleware

  • Extract Token from Authorization Header:

    // app/Http/Middleware/AuthenticateJWT.php
    public function handle($request, Closure $next)
    {
        $token = $request->bearerToken();
        if (!$token) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
    
        try {
            $decoded = JWT::decode($token, new Key(config('jwt.secret'), 'HS256'));
            $request->merge(['user' => $decoded]);
            return $next($request);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid token'], 401);
        }
    }
    
  • Register Middleware:

    // app/Http/Kernel.php
    protected $routeMiddleware = [
        'jwt.auth' => \App\Http\Middleware\AuthenticateJWT::class,
    ];
    

3. Asymmetric Keys (RS256/ES256)

  • Store Keys Securely: Use Laravel's config or environment variables:

    JWT_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----\n...
    JWT_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\n...
    

    Load in config/jwt.php:

    return [
        'private_key' => env('JWT_PRIVATE_KEY'),
        'public_key'  => env('JWT_PUBLIC_KEY'),
    ];
    
  • Encode/Decode:

    $jwt = JWT::encode($payload, config('jwt.private_key'), 'RS256');
    $decoded = JWT::decode($jwt, new Key(config('jwt.public_key'), 'RS256'));
    

4. Key Rotation with JWKS

  • Fetch and Cache JWKS:

    use Firebase\JWT\CachedKeySet;
    use GuzzleHttp\Client;
    
    $keySet = new CachedKeySet(
        'https://your-api.com/.well-known/jwks.json',
        new Client(),
        new \GuzzleHttp\Psr7\HttpFactory(),
        new \PhpFastCache\CacheManager('files')
    );
    $decoded = JWT::decode($jwt, $keySet);
    
  • Laravel Cache Integration: Use Illuminate\Cache\CacheManager as the cache pool:

    $cache = app('cache')->store('file');
    $keySet = new CachedKeySet($jwksUri, $httpClient, $httpFactory, $cache);
    

5. Testing Tokens

  • Mock JWT in Tests:

    use Firebase\JWT\JWT;
    
    $payload = ['user_id' => 1];
    $token = JWT::encode($payload, 'test-key', 'HS256');
    
    $this->withHeader('Authorization', 'Bearer ' . $token)
         ->get('/api/protected')
         ->assertOk();
    
  • Assertions for Exceptions:

    $this->expectException(\Firebase\JWT\ExpiredException::class);
    JWT::decode($expiredToken, new Key('key', 'HS256'));
    

Gotchas and Tips

1. Common Pitfalls

  • Algorithm Mismatch:

    • Error: UnexpectedValueException: Algorithm does not match key.
    • Fix: Ensure the algorithm in JWT::encode() matches the key type (e.g., HS256 for symmetric keys, RS256 for RSA).
    • Debug: Check JWT::$leeway if tokens expire prematurely due to clock skew.
  • Key Format Issues:

    • Error: DomainException: Invalid key.
    • Fix:
      • For RSA keys, ensure they are in PEM format and properly escaped in PHP strings (use double quotes for \n).
      • For EdDSA, ensure keys are base64-encoded and compatible with libsodium.
    • Example:
      // Correct (double quotes for newlines)
      $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n...";
      
  • Missing Claims:

    • Error: ExpiredException or BeforeValidException even with valid timestamps.
    • Fix: Ensure iat (issued at) and exp (expiration) claims are included in the payload.
  • Libsodium Dependency:

    • Error: DomainException: libsodium is required but not available.
    • Fix: Install paragonie/sodium_compat or enable libsodium in PHP:
      pecl install channel://pecl.php.net/libsodium
      

2. Debugging Tips

  • Decode Without Verification (Caution!): Manually inspect JWT structure (for debugging only):

    list($headerB64, $payloadB64, $signature) = explode('.', $jwt);
    $header = json_decode(base64_decode($headerB64));
    $payload = json_decode(base64_decode($payloadB64));
    

    Warning: This bypasses security! Use only for debugging.

  • Log Exceptions: Wrap JWT::decode() in a try-catch to log errors:

    try {
        $decoded = JWT::decode($jwt, $key);
    } catch (\Exception $e) {
        \Log::error("JWT Decode Error: " . $e->getMessage());
        throw $e;
    }
    
  • Validate Token Structure: Use a regex to check JWT format before processing:

    if (!preg_match('/^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/', $jwt)) {
        throw new \InvalidArgumentException('Invalid JWT format');
    }
    

3. Performance Optimization

  • Cache Key Sets: For JWKS endpoints, use CachedKeySet to avoid repeated HTTP requests:

    $keySet = new CachedKeySet($jwksUri, $httpClient, $httpFactory, $cache, 3600); // Cache for 1 hour
    
  • Precompute Keys: If using multiple keys, precompute the Key objects and store them in a service container:

    $this->app->bind('jwt.keys', function () {
        return collect(config
    
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