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

Jwt Laravel Package

mishal/jwt

Lightweight PHP JSON Web Token (JWT) library with support for None, HS256 (HMAC SHA-256), and RS256 (RSA SHA-256). Simple encode/decode API with allowed-algorithm validation and support for standard reserved claims like exp, nbf, iss, and aud.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require mishal/jwt
    
  2. Basic token generation (HMAC-SHA256):
    use Jwt\Jwt;
    use Jwt\Algorithm\HS256Algorithm;
    
    $secret = config('jwt.secret'); // Store in config/jwt.php
    $algorithm = new HS256Algorithm($secret);
    
    $payload = ['user_id' => 123, 'role' => 'admin'];
    $token = Jwt::encode($payload, $algorithm);
    
  3. Token decoding/verification (in middleware or controller):
    try {
        $decoded = Jwt::decode($token, ['algorithm' => $algorithm]);
        $userId = $decoded['user_id'];
    } catch (\Jwt\Exception\ExpiredException $e) {
        abort(401, 'Token expired');
    }
    

First Use Case: API Authentication

  • Store tokens in Authorization: Bearer <token> headers.
  • Use middleware to validate tokens before processing requests:
    // 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, ['algorithm' => $this->algorithm]);
            $request->merge(['user' => $decoded]);
            return $next($request);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid token'], 401);
        }
    }
    

Implementation Patterns

1. Token Generation Workflow

  • Payload structure:
    $payload = [
        'user_id' => auth()->id(),
        Jwt::CLAIM_EXPIRATION => now()->addHours(1)->getTimestamp(),
        Jwt::CLAIM_ISSUER => config('app.name'),
        'metadata' => ['ip' => request()->ip()]
    ];
    
  • Algorithm selection:
    • Use HS256 for simplicity (shared secret).
    • Use RS256 for public/private key security (e.g., OAuth flows).

2. Middleware Integration

  • Global JWT validation:
    // app/Http/Kernel.php
    protected $middleware = [
        \App\Http\Middleware\AuthenticateJWT::class,
    ];
    
  • Route-specific protection:
    Route::middleware(['jwt'])->group(function () {
        Route::get('/admin', 'AdminController@index');
    });
    

3. Payload Verification

  • Strict validation:
    $verify = [
        Jwt::CLAIM_ISSUER => config('app.name'),
        'role' => function ($role) {
            return in_array($role, ['admin', 'editor']);
        },
        Jwt::CLAIM_AUDIENCE => ['api', 'mobile-app']
    ];
    Jwt::decode($token, ['algorithm' => $algorithm, 'verify' => $verify]);
    

4. Token Refresh Logic

  • Short-lived access tokens + long-lived refresh tokens:
    // Issue refresh token (RS256, expires in 30 days)
    $refreshToken = Jwt::encode([
        'user_id' => 123,
        Jwt::CLAIM_EXPIRATION => now()->addDays(30)->getTimestamp(),
        'token_type' => 'refresh'
    ], $rsaAlgorithm);
    
    // Issue access token (HS256, expires in 1 hour)
    $accessToken = Jwt::encode([
        'user_id' => 123,
        Jwt::CLAIM_EXPIRATION => now()->addHour()->getTimestamp(),
        'refresh_token' => $refreshToken
    ], $hsAlgorithm);
    

5. Custom Claims

  • Extend payloads for business logic:
    $payload = [
        'user_id' => 123,
        'permissions' => ['create_post', 'edit_profile'],
        'tier' => 'premium'
    ];
    

Gotchas and Tips

Pitfalls

  1. Algorithm Security:

    • Never use NoneAlgorithm in production (tokens are unsigned).
    • Always specify allowed algorithms during decode to prevent downgrade attacks:
      Jwt::decode($token, ['algorithm' => [$hsAlgorithm, $rsaAlgorithm]]);
      
  2. Clock Skew:

    • Set leeway for exp/nbf claims to account for server time differences:
      Jwt::decode($token, ['algorithm' => $algorithm, 'leeway' => 60]); // 60 sec
      
  3. Secret Management:

    • HS256 secrets must be kept confidential (store in .env or vault).
    • RSA keys: Ensure private keys are never exposed. Use openssl to generate:
      openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
      openssl rsa -pubout -in private_key.pem -out public_key.pem
      
  4. Token Size Limits:

    • JWTs can grow large with complex payloads. Avoid storing large data (e.g., user profiles) in tokens. Use token claims to reference database IDs instead.
  5. Error Handling:

    • Catch specific exceptions for granular responses:
      try {
          $decoded = Jwt::decode($token, ['algorithm' => $algorithm]);
      } catch (\Jwt\Exception\SignatureInvalidException $e) {
          return response()->json(['error' => 'Invalid token signature'], 401);
      } catch (\Jwt\Exception\TokenNotProvidedException $e) {
          return response()->json(['error' => 'Token not provided'], 401);
      }
      

Debugging Tips

  1. Decode without verification (for debugging):
    $decoded = Jwt::decode($token, ['algorithm' => $algorithm, 'verify' => false]);
    
  2. Inspect token parts (header.payload.signature):
    list($header, $payload, $signature) = explode('.', $token);
    $decodedPayload = base64_decode(strtr($payload, '-_', '+/'));
    
  3. Log validation failures:
    try {
        $decoded = Jwt::decode($token, ['algorithm' => $algorithm, 'verify' => $verify]);
    } catch (\Jwt\Exception\VerificationException $e) {
        \Log::error("JWT Verification Failed", [
            'claim' => $e->getClaim(),
            'code' => $e->getCode(),
            'token' => $token
        ]);
        throw $e;
    }
    

Extension Points

  1. Custom Algorithms:

    • Implement Jwt\Algorithm\AlgorithmInterface for unsupported algorithms (e.g., ECDSA).
  2. Payload Transformers:

    • Decorate payloads before encoding/after decoding:
      $payload = [
          'user' => User::find($userId)->toArray(),
          'metadata' => ['device' => request()->userAgent()]
      ];
      
  3. Token Storage:

    • Store tokens in HTTP-only cookies for web apps or secure headers for APIs.
    • Use same-site and secure flags for cookies:
      $response = response()->json(['token' => $token]);
      $response->withCookie(cookie('jwt', $token, 60 * 24, null, null, true, true));
      
  4. Revocation:

    • Since JWTs are stateless, implement a revocation table in the database:
      // Before decoding, check revocation status
      if (Token::where('token', $token)->where('revoked_at', null)->exists()) {
          throw new \Jwt\Exception\TokenRevokedException();
      }
      

Performance Considerations

  • Avoid decoding tokens unnecessarily (e.g., in non-authenticated routes).
  • Cache decoded payloads if the same token is used frequently (e.g., in a request loop).
  • Use RS256 for public APIs to avoid secret rotation overhead.

Security Best Practices

  • Rotate secrets/keys periodically (e.g., every 3–6 months).
  • Use short expiration times for access tokens (e.g., 15–60 minutes).
  • Avoid storing sensitive data in tokens (e.g., passwords, PII).
  • Validate aud (audience) claims to restrict token usage to specific clients.
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle