Skip to content
Plugins (190)

jwt

stable

Create and verify HMAC-signed JSON Web Tokens (HS256, HS384, HS512) and inspect their claims.

use plugin jwt
7 functions Cryptography
Runs with the native Zolo host

Plugin snippets can be edited in the Playground, but native capabilities are executed locally with the Zolo CLI.

/ filter jk navigate Esc clear
Functions (7)
  1. encode Sign a JSON payload and return a JWT string
  2. verify Check the HMAC signature, independently of expiration
  3. decode_parts Inspect the header, payload, and encoded signature
  4. decode_header Inspect the header's algorithm and token type
  5. decode_payload Read the payload JSON without verifying it
  6. get_claim Read a claim as text, or nil if it is absent
  7. is_expired Compare the expiration claim with a Unix timestamp

From import to result

  1. 01Import only what you use
  2. 02Copy the smallest example
  3. 03Run it with the Zolo CLI

Overview

jwt signs JSON payloads with a shared secret using HS256, HS384, or HS512. Run these complete examples with the Zolo CLI and the jwt plugin installed. The native plugin is not included in the browser playground.

JSON is text: use r#"..."# to keep its quotes and braces literal. Single quotes are reserved for one character, such as 'a'.

The examples use a fixed clock and a demonstration secret so their output is repeatable. In an application, supply the current Unix timestamp and load your signing secret from configuration. verify checks the signature; expiration is a separate check. Decoding a token does not authenticate its contents.

Common patterns

Accept a session before reading its permissions

Issue a short session, then check its signature and expiration before reading the user's identity and role. The fixed clock represents the receiving request.

use plugin jwt::{encode, verify, is_expired, get_claim}

let secret = "demo-session-secret"
let now: float = 1700000000
let payload = r#"{"sub":"user_42","role":"editor","exp":1700003600}"#
let token = encode(payload, secret, "HS256")

if !verify(token, secret, "HS256") {
    print("session rejected: invalid signature")
} else if is_expired(token, now) {
    print("session rejected: expired")
} else {
    let user = get_claim(token, "sub")
    let role = get_claim(token, "role")
    print("signed in as {user}")
    print("role: {role}")
}
signed in as user_42
role: editor

Reject an expired session or an incorrect secret

Both failure paths are observable without a server or an external service.

use plugin jwt::{encode, verify, is_expired}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"alice","exp":1700000000}"#, secret)

print(verify(token, "incorrect-secret"))
print(is_expired(token, 1700000000))
false
true

Inspect token metadata

Inspect the header for debugging. It remains untrusted until verification.

use plugin jwt::{encode, decode_header, verify}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"bob"}"#, secret, "HS384")
let header = decode_header(token)
print(header["alg"])
print(header["typ"])
print(verify(token, secret, "HS384"))
HS384
JWT
true

Sign a JSON payload and return a JWT string

Signs valid JSON. The default algorithm is HS256.

use plugin jwt::{encode, verify}

let secret = "demo-session-secret"
let payload = r#"{"sub":"user_42","exp":1700003600}"#
let token = encode(payload, secret)
print(verify(token, secret, "HS256"))
true

Choose HS512 explicitly when both sides use that algorithm:

use plugin jwt::{encode, verify}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"user_42"}"#, secret, "HS512")
print(verify(token, secret, "HS512"))
true

Check the HMAC signature, independently of expiration

Returns whether the HMAC signature matches. If no algorithm is supplied, the plugin reads it from the header. An explicit algorithm selects the HMAC used for verification. This function does not validate expiration or application claims such as audience and issuer.

use plugin jwt::{encode, verify}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"alice"}"#, secret, "HS512")
print(verify(token, secret, "HS512"))
print(verify(token, "incorrect-secret", "HS512"))
print(verify(token, secret, "HS256"))
true
false
false

Inspect the header, payload, and encoded signature

Returns the decoded header and payload JSON strings and the base64url signature. This is inspection, without signature verification.

use plugin jwt::{encode, decode_parts}

let token = encode(r#"{"sub":"alice","role":"editor"}"#, "demo-session-secret")
let parts = decode_parts(token)
print(parts["header"])
print(parts["payload"])
{"alg":"HS256","typ":"JWT"}
{"sub":"alice","role":"editor"}

Inspect the header's algorithm and token type

Returns the header's alg and typ fields.

use plugin jwt::{encode, decode_header}

let token = encode(r#"{"sub":"bob"}"#, "demo-session-secret", "HS384")
let header = decode_header(token)
print(header["alg"])
print(header["typ"])
HS384
JWT

Read the payload JSON without verifying it

Reads the raw payload JSON. Verify the signature before using it for decisions.

use plugin jwt::{encode, verify, decode_payload}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"alice","role":"editor"}"#, secret)
if verify(token, secret, "HS256") {
    print(decode_payload(token))
}
{"sub":"alice","role":"editor"}

Read a claim as text, or nil if it is absent

Returns strings unchanged; numbers and booleans become text. A missing claim returns nil. This function does not verify the signature.

use plugin jwt::{encode, verify, get_claim}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"user_7","active":true,"exp":1700003600}"#, secret)
if verify(token, secret, "HS256") {
    print(get_claim(token, "sub"))
    print(get_claim(token, "active"))
    print(get_claim(token, "exp"))
    if get_claim(token, "display_name") == nil {
        print("display name not set")
    }
}
user_7
true
1700003600
display name not set

Compare the expiration claim with a Unix timestamp

Returns true when a numeric exp is less than or equal to now_unix. An absent or nonnumeric exp returns false; this function does not require expiration to be present and does not verify the signature.

use plugin jwt::{encode, is_expired}

let secret = "demo-session-secret"
let token = encode(r#"{"sub":"alice","exp":1700003600}"#, secret)
print(is_expired(token, 1700003599))
print(is_expired(token, 1700003600))

let no_expiration = encode(r#"{"sub":"alice"}"#, secret)
print(is_expired(no_expiration, 1700003600))
false
true
false

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

en