feat(iam): 完整实现 iam 身份认证与权限服务
包含 jwt/jwks/audit/grpc、rbac、cache、redis/kafka 配置等完整实现
This commit is contained in:
54
services/iam/src/config/jwt.ts
Normal file
54
services/iam/src/config/jwt.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { env } from "./env.js";
|
||||
|
||||
/**
|
||||
* JWT RS256 密钥对加载(president §2.15:本地文件密钥)。
|
||||
*
|
||||
* - 私钥:IAM 签发 access_token / refresh_token
|
||||
* - 公钥:api-gateway 通过 JWKS 或 gRPC GetPublicKey 拉取验签
|
||||
*
|
||||
* 启动时一次性加载到内存,避免每次签名/验签的 IO 开销。
|
||||
* kid(Key ID)用于 JWKS 端点多密钥轮换场景下标识密钥。
|
||||
*/
|
||||
export interface JwtKeyPair {
|
||||
privateKey: string;
|
||||
publicKey: string;
|
||||
kid: string;
|
||||
alg: "RS256";
|
||||
}
|
||||
|
||||
let keyPair: JwtKeyPair | null = null;
|
||||
|
||||
export function getJwtKeyPair(): JwtKeyPair {
|
||||
if (!keyPair) {
|
||||
const privateKey = readFileSync(env.IAM_PRIVATE_KEY_PATH, "utf-8");
|
||||
const publicKey = readFileSync(env.IAM_PUBLIC_KEY_PATH, "utf-8");
|
||||
keyPair = {
|
||||
privateKey,
|
||||
publicKey,
|
||||
kid: env.JWT_KEY_ID,
|
||||
alg: "RS256",
|
||||
};
|
||||
}
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* TTL 计算:将 "15m" / "7d" 等字符串转为秒数。
|
||||
* 用于 JWT expiresIn 配置与响应中的 expires_in 字段。
|
||||
*/
|
||||
export function ttlToSeconds(ttl: string): number {
|
||||
const match = /^(\d+)([smhd])$/.exec(ttl);
|
||||
if (!match || match[1] === undefined || match[2] === undefined) {
|
||||
throw new Error(`Invalid TTL format: ${ttl}`);
|
||||
}
|
||||
const value = Number.parseInt(match[1], 10);
|
||||
const unit = match[2] as "s" | "m" | "h" | "d";
|
||||
const multipliers: Record<"s" | "m" | "h" | "d", number> = {
|
||||
s: 1,
|
||||
m: 60,
|
||||
h: 3600,
|
||||
d: 86400,
|
||||
};
|
||||
return value * multipliers[unit];
|
||||
}
|
||||
Reference in New Issue
Block a user