@arraypress/hmac-tokens
v1.0.0
Published
Create and verify HMAC-SHA256 signed tokens with expiry. Web Crypto API — works everywhere.
Maintainers
Readme
@arraypress/hmac-tokens
Create and verify HMAC-SHA256 signed tokens with expiry. A lightweight alternative to JWT for simple use cases like magic links, download URLs, and API tokens.
Two functions. Zero dependencies. Uses the Web Crypto API — works in Cloudflare Workers, Node.js 18+, Deno, Bun, and browsers.
Installation
npm install @arraypress/hmac-tokensUsage
import { createToken, verifyToken } from '@arraypress/hmac-tokens';
// Create a token with any JSON payload
const token = await createToken(
{ email: '[email protected]' },
'your-secret-key',
{ expiresIn: 900 } // 15 minutes
);
// → 'eyJwIjp7ImVtYW...' (URL-safe string)
// Verify and decode
const payload = await verifyToken(token, 'your-secret-key');
// → { email: '[email protected]' } (or null if invalid/expired)API
createToken(payload, secret, options?)
Create a signed token. The payload can be any JSON-serializable value — string, number, object, array.
Options:
expiresIn— Token lifetime in seconds. Default:3600(1 hour).
Returns a URL-safe string (no +, /, or = characters) suitable for query parameters, headers, or cookies.
verifyToken(token, secret)
Verify a token and return the decoded payload. Returns null if:
- The token is malformed
- The HMAC signature doesn't match (wrong secret or tampered)
- The token has expired
- The input is null, undefined, or empty
Examples
// Magic link (15 min expiry)
const token = await createToken({ email: '[email protected]' }, secret, { expiresIn: 900 });
const url = `https://store.com/login?token=${token}`;
// Download link (24h expiry)
const token = await createToken({ orderId: 'pi_xxx', fileId: 42 }, secret, { expiresIn: 86400 });
const url = `https://store.com/download?token=${token}`;
// API key (30 days)
const token = await createToken({ userId: 'user_123', scopes: ['read'] }, secret, { expiresIn: 2592000 });Why not JWT?
JWTs are great for distributed systems with public key verification. But for simple signed tokens where the same server creates and verifies, they're overkill. This package:
- Has no dependencies (jwt libraries pull in dozens)
- Uses the Web Crypto API natively (no polyfills needed on Workers/Deno)
- Produces shorter tokens (no JWT header overhead)
- Has a simpler API (two functions vs. sign/verify/decode/algorithms)
License
MIT
