JwtVerify()

edit

Verifies a JSON Web Token (JWT) signature and returns the claims (the data payload).

Also validates expiration, not-before, issuer, and audience if specified.

Requires Extension: Crypto Extension

JwtVerify( token=string, key=any, algorithms=any, issuer=string, audience=string, clockSkew=numeric, throwOnError=boolean );

Returns: any

Argument Description Default
token
string, required
edit

JWT string to verify.

key
any, required
edit

Verification key. For HMAC: string or byte array. For RSA/EC: PEM string or Java PublicKey object.

algorithms
any, optional
edit

Allowed algorithms. Array or comma-separated string. Security best practice to restrict algorithms.

issuer
string, optional
edit

Required issuer (iss claim). Validation fails if token issuer doesn't match.

audience
string, optional
edit

Required audience (aud claim). Validation fails if audience is not in token's audience list.

clockSkew
numeric, optional
edit

Clock skew tolerance in seconds for exp/nbf validation. Default 0.

throwOnError
boolean, optional
edit

If true (default), throws on invalid token. If false, returns struct with valid, claims, error. Note: defaults to true unlike hash verify functions, since JWT validation failures typically indicate a security issue.

true

Usage Notes

edit

Always restrict algorithms in production. Without the algorithms parameter, any algorithm is accepted. This can enable algorithm confusion attacks where an attacker switches from RS256 to HS256 and signs with the public key. Always specify which algorithms you expect:

claims = JwtVerify( token = token, key = secret, algorithms = "HS256" );

throwOnError behaviour: By default, invalid tokens throw an exception. Pass throwOnError=false to get a result struct instead — useful for login flows where you want to handle errors gracefully without try/catch:

  • Valid: { valid: true, claims: { sub: "user123", ... } }
  • Invalid: { valid: false, error: "Token has expired" }

Clock skew: Distributed systems often have small clock differences. Use clockSkew (in seconds) to add tolerance when checking exp and nbf claims. A value of 30–60 seconds is typical.

Issuer and audience validation: Always validate these in production to ensure the token was issued by the expected provider and intended for your application.

Examples

edit
// Verify an HMAC-signed token - returns the claims struct on success
secret = "my-super-secret-key-that-is-at-least-256-bits-long";
token = JwtSign( { sub: "user123", role: "admin" }, secret, "HS256" );

claims = JwtVerify( token = token, key = secret ); // claims.sub == "user123", claims.role == "admin"
// Verify an RSA-signed token with the public key keyPair = GenerateKeyPair( "RSA-2048" ); token = JwtSign( claims = { sub: "user123" }, key = keyPair.private, algorithm = "RS256" ); claims = JwtVerify( token = token, key = keyPair.public );
// By default, invalid tokens throw an exception. Use throwOnError=false to get // a result struct instead - useful for login flows where you want to handle errors gracefully result = JwtVerify( token = token, key = "wrong-key", throwOnError = false ); // result.valid == false, result.error contains the error message
result = JwtVerify( token = token, key = keyPair.public, throwOnError = false ); // result.valid == true, result.claims contains the decoded claims
// Validate issuer and audience - throws if they don't match token = JwtSign( claims = { sub: "user123" }, key = secret, algorithm = "HS256", issuer = "https://myapp.com", audience = "api" ); claims = JwtVerify( token = token, key = secret, issuer = "https://myapp.com", audience = "api" );
// Allow clock skew for expiration checks (useful for distributed systems) // This allows tokens up to 60 seconds past their expiration claims = JwtVerify( token = token, key = secret, clockSkew = 60 );
// Restrict which algorithms are accepted (security best practice) claims = JwtVerify( token = token, key = secret, algorithms = [ "HS256", "HS384" ] ); // or as a comma-separated string claims = JwtVerify( token = token, key = secret, algorithms = "HS256,HS384" );
// Positional arguments: token, key claims = JwtVerify( token, secret );

See also