JWT signing and verification, Bearer token parsing, webhook signature checks, constant-time comparison.
import { parseBearer, jwtVerify, jwtSign } from "zigttp:auth";
function handler(req) {
const token = parseBearer(req.headers["authorization"]);
if (token === undefined) {
return Response.json({ error: "unauthorized" }, { status: 401 });
}
const auth = jwtVerify(token, env("JWT_SECRET") ?? "");
if (!auth.ok) {
return Response.json({ error: auth.error }, { status: 401 });
}
return Response.json({ user: auth.value });
}| Export | Signature | Returns | Purpose |
|---|---|---|---|
parseBearer |
parseBearer(header): string | undefined |
optional string | Extract the token from an Authorization: Bearer ... header. |
jwtVerify |
jwtVerify(token, secret, options?): Result<Claims> |
Result | Verify HS256 signature and exp / nbf claims. |
jwtSign |
jwtSign(claims, secret): string |
string | Sign an HS256 JWT. |
verifyWebhookSignature |
verifyWebhookSignature(body, signature, secret): boolean |
boolean | HMAC-SHA256 check for a webhook payload. |
timingSafeEqual |
timingSafeEqual(a, b): boolean |
boolean | Constant-time string comparison. |
Claims is the decoded JSON payload, treated as an unknown record.
Callers narrow with runtime checks or decodeJson before use.
jwtVerify()sets thebearer_authcontract flag; proven properties for the handler includeauthenticatedwhen every response branch passes through a successful verify.- Labels the returned value as
credential+validatedso the flow checker can prevent credential leakage into egress.
jwtVerify()returns{ ok: false, error }on bad signature, expired token, or malformed JWT. Check.okbefore.value.jwtSign()throws synchronously on non-string claims or secrets.
- A non-empty secret. Reading the secret from
env()is the idiomatic path; sound mode rejectsjwtVerify(token, "")as a critical failure because the absorbing law folds it toresult_err.
zigttp:crypto- lower-level HMAC / SHA256 / base64.zigttp:validate- schema-backed validation for claim payloads once decoded.