nixilla/php-jwt
Lightweight PHP JWT library for creating and validating JSON Web Tokens. Sign and verify tokens with common algorithms, manage claims (exp/iat/nbf), and handle key/secret configuration. Suitable for simple auth and API token workflows.
Installation
composer require nixilla/php-jwt
Ensure your PHP version is 7.2+ (check composer.json for compatibility).
First Use Case: Signing a JWT
use Nixilla\JWT\JWT;
$jwt = new JWT();
$secretKey = 'your-256-bit-secret'; // Must be at least 32 chars for HS256
$payload = [
'iss' => 'your-app',
'iat' => time(),
'data' => ['user_id' => 123]
];
$token = $jwt->encode($payload, $secretKey);
// Output: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
Decoding a JWT
$decoded = $jwt->decode($token, $secretKey, ['HS256']);
// Returns array of payload data
Verify Token Existence
if ($jwt->verify($token, $secretKey, ['HS256'])) {
// Token is valid
}
src/Nixilla/JWT/JWT.php.tests/ directory for usage patterns (e.g., JWTTest.php).API Authentication Middleware
// app/Http/Middleware/VerifyJWT.php
public function handle($request, Closure $next) {
$token = $request->bearerToken();
$jwt = new JWT();
$decoded = $jwt->decode($token, config('jwt.secret'), ['HS256']);
if (!$decoded) {
return response()->json(['error' => 'Invalid token'], 401);
}
$request->merge(['user' => $decoded['data']]);
return $next($request);
}
Token Generation Service
// app/Services/JWTService.php
class JWTService {
public function generateToken(array $payload): string {
$jwt = new JWT();
return $jwt->encode($payload, config('jwt.secret'), 'HS256', 3600); // 1-hour expiry
}
}
Refresh Tokens
$refreshToken = $jwt->encode([
'iss' => 'refresh',
'iat' => time(),
'exp' => time() + (86400 * 7) // 7 days
], $secretKey, 'HS256');
.env:
JWT_SECRET=your-32-char-secret-here
JWT_ALGORITHM=HS256
JWT class in AppServiceProvider:
$this->app->singleton(JWT::class, function () {
return new JWT();
});
try {
$decoded = $jwt->decode($token, $secretKey);
} catch (\Exception $e) {
Log::error("JWT decode failed: " . $e->getMessage());
return response()->json(['error' => 'Invalid token'], 401);
}
Secret Key Length
HS256 (or 512 bits for RS256).Invalid key length or Invalid signature errors.Algorithm Mismatch
HS256 using RS256 (or vice versa).decode()/verify():
$jwt->decode($token, $secretKey, ['HS256']); // Explicit algorithm
Clock Skew
exp claim).leeway in decode():
$jwt->decode($token, $secretKey, [], 300); // 5-minute leeway
No Built-in Storage
revoked_tokens).JWT::isValid() for quick checks:
if (!$jwt->isValid($token, $secretKey, ['HS256'])) {
// Handle invalid token
}
composer require firebase/php-jwt
php -r '$token="..."; $decoded = (new \Firebase\JWT\JWT())->decode($token); print_r($decoded);'
debug mode and log exceptions:
try {
$jwt->decode($token, $secretKey);
} catch (\Exception $e) {
Log::debug("JWT Error: " . $e->getMessage());
}
Custom Claims
Add non-standard claims (e.g., jti for idempotency):
$payload = [
'jti' => Str::uuid()->toString(),
'data' => [...]
];
Algorithm Switching Dynamically switch algorithms (e.g., for testing):
$algorithm = config('jwt.algorithm', 'HS256');
$jwt->decode($token, $secretKey, [$algorithm]);
Event Hooks
Extend the JWT class to add pre/post hooks:
class CustomJWT extends JWT {
public function encode($payload, $secret, $alg = 'HS256', $exp = 0) {
$this->logPayload($payload); // Custom logic
return parent::encode($payload, $secret, $alg, $exp);
}
}
Testing
Mock the JWT class in PHPUnit:
$mockJWT = $this->createMock(JWT::class);
$mockJWT->method('decode')->willReturn(['data' => ['user_id' => 1]]);
$this->app->instance(JWT::class, $mockJWT);
How can I help you explore Laravel packages today?