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 Core Laravel Package

web-token/jwt-core

Core JWT component from the web-token JWT Framework. Provides foundational building blocks for JSON Web Tokens used by the framework. Read-only split package; development and issues belong in the main jwt-framework repository. Official docs available online.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require web-token/jwt-core
    

    (Note: This package is read-only and intended for use within the JWT Framework. For Laravel integration, pair with firebase/php-jwt or spomky-labs/base64url for broader compatibility.)

  2. First Use Case: Token Verification

    use WebToken\JWT;
    use WebToken\JWT\Signature\HS256;
    
    $jwt = new JWT();
    $signature = new HS256(config('jwt.secret'));
    $decoded = $jwt->decode('your.jwt.token.here', [$signature]);
    
    // Access payload
    $payload = $decoded->getPayload();
    
  3. Where to Look First:

    • Documentation: web-token.spomky-labs.com (focus on JWT class and algorithm implementations).
    • Source Code: src/WebToken/JWT/ (core logic for encoding/decoding).
    • Laravel Integration: Use with middleware or guards (e.g., Illuminate\Auth\Guard).

Implementation Patterns

1. Middleware for API Token Validation

Create a reusable middleware to validate JWTs on protected routes:

// app/Http/Middleware/AuthenticateJWT.php
namespace App\Http\Middleware;

use Closure;
use WebToken\JWT;
use WebToken\JWT\Signature\HS256;
use WebToken\JWT\Validation\Validation;

class AuthenticateJWT {
    public function handle($request, Closure $next) {
        $token = $request->bearerToken();
        if (!$token) {
            return response()->json(['error' => 'Token not provided'], 401);
        }

        $jwt = new JWT();
        $signature = new HS256(config('jwt.secret'));
        $validation = new Validation();

        try {
            $decoded = $jwt->decode($token, [$signature]);
            $validation->validate($decoded);
            $request->merge(['user' => $decoded->getPayload()]);
            return $next($request);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid token'], 403);
        }
    }
}

Register in app/Http/Kernel.php:

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

2. Token Generation in Controllers

Generate JWTs for login/logout flows:

use WebToken\JWT\Encoding\JWSEncoding;
use WebToken\JWT\Signature\Algorithm\HS256;

public function login(Request $request) {
    $credentials = $request->validate(['email' => 'required', 'password' => 'required']);
    $user = User::where('email', $credentials['email'])->first();

    if (!$user || !Hash::check($credentials['password'], $user->password)) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    $payload = [
        'sub' => $user->id,
        'iat' => time(),
        'exp' => time() + 3600,
        'roles' => $user->roles
    ];

    $jwt = JWSEncoding::encode(
        $payload,
        new HS256(config('jwt.secret')),
        config('jwt.secret')
    );

    return response()->json(['token' => $jwt]);
}

3. Algorithm Flexibility

Support multiple algorithms (e.g., HS256 for APIs, RS256 for public clients):

$algorithms = [
    new HS256(config('jwt.secret')),
    new RS256(config('jwt.public_key'), config('jwt.private_key'))
];

$jwt->decode($token, $algorithms);

4. Payload Customization

Extend payloads with Laravel-specific data:

$payload = [
    'user_id' => $user->id,
    'permissions' => $user->permissions->toArray(),
    'aud' => ['api', 'mobile'], // Audiences
    'custom_metadata' => ['department' => 'engineering']
];

5. Integration with Laravel Auth

Create a custom guard for JWT-based authentication:

// app/Providers/AuthServiceProvider.php
protected function jwtGuard() {
    return new class extends Guard {
        public function user() {
            if (!$this->user) {
                $token = request()->bearerToken();
                if ($token) {
                    try {
                        $decoded = $this->jwt->decode($token, [$this->signature]);
                        $this->user = User::find($decoded->getPayload()['sub']);
                    } catch (\Exception $e) {
                        $this->user = null;
                    }
                }
            }
            return $this->user;
        }
    };
}

6. Testing JWT Logic

Use PEST/PHPUnit to test token generation/validation:

// tests/Feature/JWTTest.php
public function test_jwt_generation_and_validation() {
    $payload = ['user_id' => 1];
    $token = JWSEncoding::encode($payload, new HS256('secret'), 'secret');

    $decoded = JWSEncoding::decode($token, new HS256('secret'));
    expect($decoded->getPayload())->toEqual($payload);
}

Gotchas and Tips

Pitfalls

  1. Algorithm Mismatches:

    • Issue: Decoding a token signed with HS256 using RS256 will fail silently or throw an exception.
    • Fix: Always validate the algorithm in the payload (alg claim) and match it with the signature class:
      $alg = $decoded->getHeader('alg');
      if ($alg !== 'HS256') {
          throw new \Exception('Algorithm mismatch');
      }
      
  2. Key Management:

    • Issue: Hardcoded secrets in config files are insecure. Rotating keys requires reissuing all tokens.
    • Fix:
      • Use Laravel’s config with environment variables:
        JWT_SECRET=your-256-bit-secret
        JWT_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----
        JWT_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----
        
      • For production, integrate with AWS KMS, Hashicorp Vault, or Laravel’s Encrypter.
  3. Token Expiration:

    • Issue: The package does not enforce expiration (exp claim) by default.
    • Fix: Add validation logic:
      $now = time();
      $exp = $decoded->getPayload()['exp'];
      if ($exp < $now) {
          throw new \Exception('Token expired');
      }
      
  4. Payload Size Limits:

    • Issue: JWTs have a ~4KB payload limit (due to Base64URL encoding). Large payloads (e.g., user data) will fail.
    • Fix: Store minimal data in the token (e.g., user_id) and fetch the rest from the database.
  5. Asymmetric Crypto Performance:

    • Issue: RS256/ES256 are CPU-intensive and can bottleneck APIs under high load.
    • Fix:
      • Use HS256 for internal APIs.
      • Offload signing/verification to a queue (e.g., Laravel Horizon).
      • Cache public keys in Redis.
  6. No Built-in Revocation:

    • Issue: The package cannot revoke tokens without external storage (e.g., Redis, database).
    • Fix: Implement a blacklist table or use short-lived tokens with refresh tokens.
  7. PHP Version Quirks:

    • Issue: The package may not support PHP 8.1+ features (e.g., constructor property promotion).
    • Fix: Test with PHP 8.0 and polyfill missing features if needed.

Debugging Tips

  1. Decode Raw JWTs: Use jwt.io to manually decode tokens and inspect headers/payloads.

  2. Enable Detailed Errors: Catch exceptions and log them for debugging:

    try {
        $decoded = $jwt->decode($token, [$signature]);
    } catch (\WebToken\JWT\Exception\InvalidToken $e) {
        \Log::error('JWT Error: ' . $e->getMessage());
        return response()->json(['error' => 'Invalid token'], 401);
    }
    
  3. Validate Headers: Ensure the typ (type) header is set to JWT:

    $headers = $decoded->getHeader();
    if (!isset($headers['typ']) || $headers['
    
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.
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
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