@ access-tokens/ core (帮助)
管理个人访问Tokens(PATs)的核心库,使用安全的以crypt为基础的散列. 支持DynamoDB后端.
特征
- 安全托肯生成: 加密安全随机符号生成
- 闪闪发光: 采用PHC格式的工业标准密码散列
- Token 生命周期管理: 签发、核实、更新、撤销并恢复令牌
- 角色访问控制: 将任意角色附加到带有原子加/再移动操作的符号上
- DynamoDB 整合: 低成本可缩放存储, TTL 过期
- 类型脚本: 具有综合API类型的完整类型安全
安装
npm install @access-tokens/core
快速启动
import { DynamoDBPat } from "@access-tokens/core";
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
// Initialize AWS clients
const dynamoClient = new DynamoDBClient({ region: "us-east-1" });
const docClient = DynamoDBDocumentClient.from(dynamoClient);
// Create DynamoDBPat instance
const pat = new DynamoDBPat({
tableName: "my-tokens",
docClient,
});
// Issue a new token
const { token, record } = await pat.issue({
owner: "[email protected]",
isAdmin: false,
expiresAt: Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60, // 1 year
});
console.log("Token:", token); // pat_abc123...xyz
console.log("Token ID:", record.tokenId);
// Verify a token
const result = await pat.verify(token);
if (result.valid) {
console.log("Token is valid!");
console.log("Owner:", result.record.owner);
console.log("Is Admin:", result.record.isAdmin);
}
API 参考
构造器
new DynamoDBPat(options)
创建一个新的 DynamoDBPat 实例 .
选项 :
{
tableName: string; // DynamoDB table name (required)
ddbClient?: DynamoDBClient; // AWS DynamoDB Client (optional)
docClient?: DynamoDBDocumentClient; // AWS DynamoDB Document Client (optional)
tokenPrefix?: string; // Token prefix (default: "pat_")
keyLength?: number; // Scrypt key length in bytes (default: 64)
saltLength?: number; // Scrypt salt length in bytes (default: 16)
scryptOptions?: { // Scrypt configuration (optional)
cost?: number; // CPU/memory cost (default: 16384)
blockSize?: number; // Block size (default: 8)
parallelization?: number; // Parallelization (default: 1)
maxmem?: number; // Maximum memory (optional)
};
bootstrapPhc?: string; // Bootstrap PHC for key derivation (optional)
}
说明: 你只需要提供其中之一 ddbClient 或者说 docClient而不是两个.
如果两者都不提供,则将自动创建默认的DynamomDB客户端.
如果只是这样的话 ddbClient 提供文档客户端。 若为
docClient 将直接使用.
调试操作
issue(params): Promise<{ token: string; record: PatRecord }>
发行了一个新的符号.
参数:
{
owner: string; // Token owner (e.g., email address)
isAdmin: boolean; // Whether token has admin privileges
roles?: string[]; // Array of role strings (optional, max 50 roles, 100 chars each)
expiresAt?: number; // Unix timestamp for expiration (optional)
tokenId?: string; // Pre-generated token ID (optional)
}
回返情况: 包含完整符号字符串和数据库记录的对象.
verify(token: string): Promise<VerifyResult>
验证一个符号,如果有效则返回其记录.
回返情况:
{
valid: boolean;
record?: PatRecord; // Only present if valid=true
reason?: string; // Only present if valid=false
}
无效令牌的原因 :
"invalid_prefix"- 托肯前缀不符合预期的前缀"invalid_format"- 托肯格式不正确(结构化)"not_found"- 数据库中找不到托肯ID"invalid_phc"- 存储的 PHC 散列格式无效"unsupported_algorithm"- 不支持PHC中的散列算法"invalid_parameters"- PHC 中的 Scrypt 参数无效"invalid_secret"- 秘密与存储的散列不符"revoked"- 托肯已经被撤销了"expired"- 托肯已经过期了
register(params): Promise<TokenRecord>
以预生成的ID和秘密散列来注册一个符号 .
参数:
{
tokenId: string; // Token ID
secretPhc: string; // PHC-formatted secret hash
owner: string; // Token owner
isAdmin: boolean; // Admin status
roles?: string[]; // Array of role strings (optional)
expiresAt?: number; // Expiration timestamp (optional)
}
update(tokenId: string, updates): Promise<void>
更新已存在的符号属性 。 支持原子角色添加/移动操作.
参数:
tokenId: string- 需要更新的托肯IDupdates: object- 要更新的属性 :
{
owner?: string; // New owner (optional)
isAdmin?: boolean; // New admin status (optional)
roles?: RolesUpdate; // Roles update (optional, see below)
secretPhc?: string; // New secret hash (optional)
expiresAt?: number | null; // New expiration or null to remove (optional)
}
// RolesUpdate can be:
type RolesUpdate =
| string[] // Replace all roles
| { add: string[] } // Atomic add (cannot combine with remove)
| { remove: string[] } // Atomic remove (cannot combine with add)
实例:
// Update basic properties
await pat.update("34NwRzvnBbgI3uedkrQ3Q", { owner: "[email protected]" });
// Replace all roles
await pat.update("34NwRzvnBbgI3uedkrQ3Q", { roles: ["reader", "writer"] });
// Add roles atomically (idempotent)
await pat.update("34NwRzvnBbgI3uedkrQ3Q", { roles: { add: ["admin"] } });
// Remove roles atomically (idempotent)
await pat.update("34NwRzvnBbgI3uedkrQ3Q", { roles: { remove: ["guest"] } });
// Clear all roles
await pat.update("34NwRzvnBbgI3uedkrQ3Q", { roles: [] });
// Update multiple properties at once
await pat.update("34NwRzvnBbgI3uedkrQ3Q", {
owner: "[email protected]",
roles: { add: ["admin"] },
});
revoke(tokenId: string, options?: { expiresAt?: number }): Promise<void>
撤销一个标志。 可选设定自动清理到期.
示例
// Revoke immediately
await pat.revoke("34NwRzvnBbgI3uedkrQ3Q");
// Revoke with cleanup in 30 days
await pat.revoke("34NwRzvnBbgI3uedkrQ3Q", {
expiresAt: Math.floor(Date.now() / 1000) + 30 * 24 * 60 * 60,
});
restore(tokenId: string): Promise<void>
恢复先前已撤销的令牌.
示例
await pat.restore("34NwRzvnBbgI3uedkrQ3Q");
list(options?): AsyncGenerator<PublicTokenRecord>
列出所有带有可选过滤功能的符号。 返回生成令牌的同步生成器.
选项 :
{
afterTokenId?: string; // Start after this token ID (pagination)
limit?: number; // Maximum tokens to return
includeSecretPhc?: boolean; // Include secret hashes (default: false)
hasRole?: string; // Filter tokens that have this role (optional)
}
示例
// Iterate through all tokens
for await (const token of pat.list()) {
console.log(token.owner);
}
// With pagination
for await (const token of pat.list({
limit: 100,
afterTokenId: "34NwRzvnBbgI3uedkrQ3Q",
})) {
console.log(token);
}
说明: 对被撤销和过期的令牌进行过滤,应当由调用人在检索记录后进行.
托肯一代公用事业
generate(config?: { tokenId?: string }): Promise<{ token: string; tokenId: string; secretPhc: string }>
生成一个符号而不将其存储在数据库中 。 用于预生成符.
示例
// Generate new token
const { token, tokenId, secretPhc } = await pat.generate();
// Generate with specific token ID
const result = await pat.generate({ tokenId: "34NwRzvnBbgI3uedkrQ3Q" });
调试格式
Tokens 遵循格式 : {prefix}{tokenId}.{secret}
示例 pat_34NwRzvnBbgI3uedkrQ3Q.a8b9c0d1e2f3g4h5i6j7k8l9m0n1o2p3q4r5s6t7u8v9w0x1y2z3
- 前缀: 可配置( 默认 ):
pat_(中文(简体) ) - 密码: 21-字符 Base62-编码独有标识符
- 秘诀: Base64- 编码随机字节( 默认: 32 字节 = 43 Base64 字符)
警卫
- 闪闪发光: 秘密用安全默认参数进行散列
- PHC 格式: Hashes 为算法敏捷性而以Argon2-相容的 PHC 字符串格式存储
- 时间-安全比较: 经常时间比较防止时间攻击
- 安全随机生成: 使用节点.js
crypto.randomBytes()用于符号生成
迪纳摩DB Schema
图表
主密钥 :
- 分区密钥 :
tokenId(叫声)
属性 :
tokenId: 唯一符号标识符secretPhc: PHC 格式化的秘密散列owner: 托肯所有者标识符isAdmin:布尔管理旗roles:字符串 角色名集(可选的,以 DynamoDB SS 类型存储)isRevoked:布尔已取消状态expiresAt: Unix 时间戳( 可选, 启用 TTL)createdAt: 无时标updatedAt: 无时标
全球二级指数(建议):
- 索引名称 :
owner-index - 分区密钥 :
owner(叫声) - 启用高效
listByOwner()查询
TTL 配置
配置 DynamoDB TTL 上 expiresAt 属性,用于自动清理过期的符号.
处理错误
所有方法都可能会出错。 使用试捕捉器处理错误 :
try {
const result = await pat.verify(token);
if (!result.valid) {
console.log("Invalid token:", result.reason);
}
} catch (error) {
console.error("Error verifying token:", error);
}
所需资源
- 节点.js 20+
- AWS SDK v3 (英语)
- 有适当权限的 DynamoDB 表格
相关软件包
- @ access-tokens/ 表达 - 捷运路线和中间软件
- @ access-tokens/ 客户端 - PAT API的HTTP客户端
- @ access-tokens/cli (英语) - 命令行符号管理
许可证
公务员制度委员会 2025年贷款信贷有限公司.