hwtr-js
HWT 協定 github的 JavaScript 參考實作。 使用此程式庫的示例請見 hwt-demo github。
Token 格式:hwt.signature.key-id.expires-unix-seconds.format.payload
安裝
// Deno / JSR
import Hwtr from 'jsr:@hwt/hwtr-js'
// Node / Bun via JSR
// npx jsr add @hwt/hwtr-js
// Local
import Hwtr from './hwtr.js'
快速開始
// 一次性生成金鑰 — 請安全儲存結果
const keyConfig = await Hwtr.generateKeys({ type: 'Ed25519' })
// 建立實例
const hwtr = await Hwtr.factory({}, keyConfig)
// 簽署
const token = await hwtr.create({ sub: 'user:123', role: 'editor' })
// 驗證
const result = await hwtr.verify(token)
if (result.ok) {
console.log(result.data) // { sub: 'user:123', role: 'editor' }
}
API
Hwtr.factory(options, keyConfig) → Promise<Hwtr>
建議使用的建構函式。等同於 new Hwtr(options).importKeys(keyConfig)。
const hwtr = await Hwtr.factory({ expiresInSeconds: 3600 }, keyConfig)
建構選項 — 全部為可選:
| 選項 | 預設值 | 說明 |
|---|---|---|
expiresInSeconds |
60 |
預設 token 有效期 |
maxTokenLifetimeSeconds |
86400 |
硬性上限;0 = 無限制 |
leewaySeconds |
1 |
時鐘偏差容差。規格書建議不超過 5 分鐘(300 秒);不強制執行最大值。 |
maxTokenSizeBytes |
4096 |
範圍:512–16384 |
format |
'j' |
Payload codec |
signatureSize |
0 |
將 HMAC 簽章截斷為 N 個字元;0 = 完整;對非對稱金鑰忽略此設定 |
throwOnInvalid |
false |
拋出例外而非回傳 ok: false |
throwOnExpired |
false |
拋出例外而非回傳 ok: false |
throwOnGenerate |
true |
簽署失敗時拋出例外 |
throwOnEncoding |
true |
codec 失敗時拋出例外 |
金鑰生成
// 完整金鑰組 — 直接傳入 factory 或 importKeys
const keyConfig = await Hwtr.generateKeys({
count: 2, // 金鑰數量(預設:1)
current: 'primary', // 簽署金鑰的 id
type: 'Ed25519', // 演算法(預設:'HMAC')
})
// → { current, type, keys: [{ id, created, privateKey, publicKey }] }
// 單一 HMAC 金鑰
const key = Hwtr.generateKey({ id: 'main' })
// → { id, secret, created }
// 單一非對稱金鑰對
const pair = await Hwtr.generateKeyPair({ id: 'k1', type: 'ECDSA-P256' })
// → { id, created, publicKey, privateKey } (base64url SPKI/PKCS8)
支援的演算法:'HMAC'、'Ed25519'、'ECDSA-P256'、'ECDSA-P384'、'ECDSA-P521'
HMAC 為對稱式 — 僅限單一服務。跨服務驗證請使用非對稱類型。P-521 的支援因環境而異;使用前請先測試。
hwtr.importKeys(keyConfig) → Promise<Hwtr>
匯入簽署及(或)驗證金鑰。factory() 會自動呼叫此方法。
// keyConfig 結構
{
current: 'primary', // 用於簽署新 token 的金鑰 id
type: 'Ed25519',
keys: [
{ id: 'primary', created: '...', privateKey: 'BASE64URL', publicKey: 'BASE64URL' }
// HMAC: { id, created, secret }
],
publicKeys: { // 可選:來自其他服務的純驗證金鑰
'partner-key': 'BASE64URL'
}
}
支援多個金鑰以進行輪換。任何 id 與 token 之 kid 相符的金鑰均可驗證該 token。僅 id === current 的金鑰用於簽署新 token。
hwtr.create(payload, hiddenData?) → Promise<string>
以預設有效期建立 token。
const token = await hwtr.create({ sub: 'user:123' })
// hiddenData 已簽署但不嵌入 token — verifier(驗證方)必須提供相同的值
const token = await hwtr.create({ sub: 'user:123' }, { ip: '203.0.113.1' })
當 token 將超過 maxTokenSizeBytes 時,回傳 ''(若設定 throwOnInvalid 則拋出例外)。
hwtr.createWith(expiresInSeconds, payload, hiddenData?) → Promise<string>
以特定有效期建立 token。若超過 maxTokenLifetimeSeconds 則拋出例外。
const token = await hwtr.createWith(300, { sub: 'user:123', oneTime: true })
hwtr.verify(token, hiddenData?) → Promise<VerifyResult>
驗證簽章與到期時間。預設不拋出例外。
const result = await hwtr.verify(token)
// result.ok — true if valid
// result.data — decoded payload
// result.expired — true if past expiry
// result.expires — unix seconds
// result.error — present on any failure
result.error 的可能值:'hwt invalid'、'hwt invalid format'、'hwt expired'、'hwt unknown encoding "x"'、'hwt unknown key'、'hwt invalid signature'、'hwt data decoding failed'
hwtr.decode(token) → Promise<{ data, expires, error? }>
解碼 payload 而不驗證簽章或到期時間。僅供檢視使用。
跨服務驗證
僅驗證(不簽署)的服務傳入不含私有 keys 的 publicKeys:
const verifyOnly = await Hwtr.factory({}, {
type: 'Ed25519',
keys: [],
publicKeys: { 'auth-key': 'BASE64URL' }
})
金鑰分發的便利方法:
const pub = await hwtr.exportPublicKey('primary') // base64url SPKI string
const all = await hwtr.getPublicKeys() // { id: base64url, ... }
await hwtr.addPublicKey({ id, publicKeyBase64, type }) // 在執行時新增外部金鑰
Codec
'j'(JSON)是唯一的內建 codec。每個程序中需一次性註冊自訂 codec:
Hwtr.registerFormat('name', {
encode(data) { /* → Uint8Array */ },
decode(buffer) { /* → value */ }
})
Hwtr.formats // → ['j', 'name', ...]
格式名稱:/^[a-zA-Z][a-zA-Z0-9]{1,19}$/。已註冊的名稱會拋出例外。
支援 Date、BigInt、Map、Set 與 typed array 的擴充 JSON codec(jx)可在原始碼儲存庫的 hwtr.formats.js 中取得 — 不包含在發布套件中。
工具函式
Hwtr.timingSafeEqual(a, b) // 固定時間比較;接受字串或 Uint8Array
Hwtr.bufferToBase64Url(buffer) // ArrayBuffer | Uint8Array → base64url string
Hwtr.base64urlToUint8Array(str) // base64url → Uint8Array;輸入無效時回傳空陣列
Hwtr.textToBase64Url(text) // UTF-8 string → base64url
Hwtr.base64urlToText(str) // base64url → UTF-8 string
Hwtr.isHwt(str) // 若 str 包含合理的 HWT 簽章段則回傳 true
Hwtr.ALGORITHMS // 支援的演算法映射
Hwtr.version // 版本
以上均可從 hwtr.js 以具名匯出(named export)方式取得。
相關資源
授權條款
Copyright 2026 Jim Montgomery
SPDX-License-Identifier: Apache-2.0
Apache License 2.0。請參閱 LICENSE。