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

Lib Jwt Laravel Package

beyondbluesky/lib-jwt

libJWT makes JWT tokens easy to encode and decode for OAuth2 authentication workflows. Lightweight PHP library updated for PHP 8.4 (2026-03-28), designed to simplify handling and validating JWTs in your applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require beyondbluesky/lib-jwt
    

    Add to composer.json if using a custom package:

    "repositories": [{
        "type": "vcs",
        "url": "https://github.com/beyondbluesky/lib-jwt"
    }]
    
  2. First Use Case: Token Generation

    use BeyondBluesky\LibJWT\JWT;
    
    $jwt = new JWT();
    $payload = [
        'user_id' => 123,
        'exp' => time() + 3600, // 1 hour expiry
        'iss' => 'your-app-name'
    ];
    $secret = 'your-secret-key'; // Store securely (e.g., .env)
    $token = $jwt->encode($payload, $secret);
    
  3. First Use Case: Token Decoding

    $decoded = $jwt->decode($token, $secret);
    // Returns array of claims or throws exception on failure
    

Where to Look First

  • README.md: Focus on the JWT class methods (encode(), decode(), verify()).
  • Source Code: src/JWT.php for core logic (minimal, ~50 lines).
  • Tests: tests/ for usage examples (if available).

Implementation Patterns

Common Workflows

1. Secure Token Generation

$jwt = new JWT();
$payload = [
    'sub' => 'user@example.com',
    'iat' => time(),
    'exp' => time() + (60 * 60), // 1 hour
    'roles' => ['admin', 'user']
];
$token = $jwt->encode($payload, config('jwt.secret'));

2. Middleware for API Authentication

// app/Http/Middleware/AuthenticateJWT.php
public function handle($request, Closure $next) {
    $token = $request->bearerToken();
    if (!$token) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    $jwt = new JWT();
    try {
        $decoded = $jwt->decode($token, config('jwt.secret'));
        $request->merge(['user' => $decoded]);
        return $next($request);
    } catch (\Exception $e) {
        return response()->json(['error' => 'Invalid token'], 401);
    }
}

3. Refresh Tokens

// Generate refresh token with longer expiry
$refreshPayload = [
    'sub' => 'user@example.com',
    'exp' => time() + (60 * 60 * 24 * 7), // 1 week
    'type' => 'refresh'
];
$refreshToken = $jwt->encode($refreshPayload, config('jwt.secret'));

// Use refresh token to get new access token
$decodedRefresh = $jwt->decode($refreshToken, config('jwt.secret'));
if ($decodedRefresh['type'] === 'refresh') {
    $accessToken = $jwt->encode($accessPayload, config('jwt.secret'));
}

4. Integration with Laravel Auth

// app/Providers/AuthServiceProvider.php
protected function boot() {
    Passport::tokensExpireIn(Carbon::now()->addDays(15));
    Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

    Passport::personalAccessTokensExpireIn(Carbon::now()->addYears(1));
    Passport::tokenableModel(User::class, 'oauth_access_tokens');

    // Custom JWT guard
    Auth::viaRequest('jwt', function ($request) {
        $jwt = new JWT();
        try {
            $token = $request->bearerToken();
            $decoded = $jwt->decode($token, config('jwt.secret'));
            return User::find($decoded['user_id']);
        } catch (\Exception $e) {
            return null;
        }
    });
}

Laravel-Specific Tips

  • Store Secrets: Use Laravel’s .env for JWT_SECRET:
    JWT_SECRET=your-256-bit-secret-key-here
    
  • Config File: Publish the package’s config (if available) or create a custom config:
    // config/jwt.php
    return [
        'secret' => env('JWT_SECRET'),
        'algorithm' => 'HS256',
        'expire' => 3600,
    ];
    
  • Service Container: Bind the JWT class for dependency injection:
    // app/Providers/AppServiceProvider.php
    public function register() {
        $this->app->singleton(JWT::class, function ($app) {
            return new JWT();
        });
    }
    

Gotchas and Tips

Pitfalls

  1. No Built-in Key Management

    • The package does not handle key rotation or storage. Use Laravel’s config or a dedicated service (e.g., AWS KMS, Hashicorp Vault).
    • Workaround: Extend the JWT class to fetch secrets dynamically:
      class CustomJWT extends JWT {
          public function getSecret() {
              return config('jwt.secret');
          }
      }
      
  2. No Automatic Token Validation

    • Unlike firebase/php-jwt, this library does not validate claims (e.g., exp, nbf) by default. Always manually check:
      $decoded = $jwt->decode($token, $secret);
      if ($decoded['exp'] < time()) {
          throw new Exception('Token expired');
      }
      
  3. PHP 8.4 Compatibility Note

    • The README claims PHP 8.4 support, but the package may lack type safety. Test thoroughly with:
      composer require --dev phpunit/phpunit
      vendor/bin/phpunit
      
  4. No Standard Claims Handling

    • The library treats all payloads as generic arrays. For structured claims (e.g., iss, sub), enforce a schema:
      $requiredClaims = ['iss', 'sub', 'exp'];
      foreach ($requiredClaims as $claim) {
          if (!array_key_exists($claim, $decoded)) {
              throw new Exception("Missing required claim: {$claim}");
          }
      }
      
  5. No Built-in Revocation

    • Tokens cannot be revoked after issuance. Use a short-lived access token + long-lived refresh token pattern:
      // Store refresh tokens in DB with revocation flag
      $refreshToken = $jwt->encode($refreshPayload, $secret);
      DB::table('refresh_tokens')->insert([
          'token' => $refreshToken,
          'user_id' => $userId,
          'revoked' => false,
      ]);
      

Debugging Tips

  1. Decode Without Verification Use decode() (not verify()) to inspect tokens:

    try {
        $decoded = $jwt->decode($token, $secret);
        var_dump($decoded); // Debug payload
    } catch (\Exception $e) {
        var_dump($e->getMessage());
    }
    
  2. Algorithm Mismatch Errors If using RS256/RS512, ensure the package supports it (it likely doesn’t). Fall back to HS256 or switch libraries:

    // Force HS256 if needed
    $jwt->setAlgorithm('HS256');
    
  3. Time Skew Issues If tokens expire prematurely, check server time synchronization:

    // Compare with UTC
    $decoded['exp'] > time() + 60; // Allow 1-minute buffer
    

Extension Points

  1. Custom Claims Validation Extend the JWT class to add validation:

    class ValidatingJWT extends JWT {
        public function decode($token, $secret) {
            $decoded = parent::decode($token, $secret);
            $this->validateClaims($decoded);
            return $decoded;
        }
    
        protected function validateClaims(array $claims) {
            if (!isset($claims['iss']) || $claims['iss'] !== config('app.name')) {
                throw new Exception('Invalid issuer');
            }
        }
    }
    
  2. Add Metadata to Tokens Include request context (e.g., IP, user agent):

    $payload = [
        'user_id' => 123,
        'meta' => [
            'ip' => request()->ip(),
            'user_agent' => request()->userAgent(),
        ],
    ];
    
  3. Logging Decoded Tokens Log payloads for auditing (avoid logging secrets):

    $decoded = $jwt->decode($token, $secret);
    \Log::info('JWT Decoded', ['claims' => $decoded, 'context' => request()->header()]);
    
  4. Rate Limiting Combine with

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.
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager