NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
JWT for Laravel

Verifying tokens

Any app holding the public key verifies user tokens offline — no database lookup and no call back to the issuer:

$claims = Jwt::verify($jwt);   // or app(UserTokenVerifier::class)->verify($jwt)
$claims->string('sub');
$claims->list('permissions');

Jwt::verify($jwt, 'app-clients');      // pin another audience for this call
Jwt::guard('clients')->verify($jwt);   // …or the audience of a configured guard

verify() checks the signature, exp, nbf and iat within the configured leeway, and pins iss and aud. Scope, denylist and token-version checks belong to the guard, not verify(). An explicit empty audience throws JwtMisconfigured.

Typed claim accessors

Claims is an immutable bag produced only after the signature and time checks pass:

$claims->has('org');            // bool
$claims->get('org');            // mixed, null when absent
$claims->require('org');        // mixed, throws ClaimMismatch when absent
$claims->string('sub');         // string
$claims->int('exp');            // int
$claims->list('permissions');   // list<string>
$claims->all();                 // array<string, mixed>
MethodReturnsBehaviour
has($name)boolWhether the claim is present.
get($name)mixedThe value, or null when absent.
require($name)mixedThrows ClaimMismatch when absent.
string($name)stringThrows ClaimMismatch when absent or not a string.
int($name)intAccepts whole floats such as 1.0; throws on fractional or non-numeric values.
list($name)list<string>Throws unless the claim is a list of strings.
sessionId()?stringThe sid claim, or null when absent.
authMethods()list<string>The amr claim, or [] when absent.
authTime()?intThe auth_time claim, or null when absent.
all()arrayThe whole claim map.

Handling failures

Invalid tokens throw a JwtException subclass. Minting a claim set that can’t be JSON-encoded throws UnencodableClaims — also a JwtException — so one catch covers both minting and verifying:

use RoundlyConsulting\Jwt\Facades\Jwt;
use RoundlyConsulting\Jwt\Jose\Exceptions\JwtException;
use RoundlyConsulting\Jwt\Jose\Exceptions\TokenExpired;

try {
    $claims = Jwt::verify($jwt);
} catch (TokenExpired $e) {
    // Prompt a re-login / refresh flow.
} catch (JwtException $e) {
    // Any other token failure: 401.
}

A failed Jwt::verify() dispatches TokenVerificationFailed before rethrowing. See Exceptions for the full hierarchy.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.