CHAPTER 09
JWT 鉴权
对应文件:
- 接口:
include/jwt.h - 实现:
src/jwt.cpp
1. 模块定位
该模块实现:
- JWT 生成与验证(HS256)
- claims 解析
- TTL 解析(如
30m、7d) - 密码哈希与验证(PBKDF2 风格循环 HMAC-SHA256)
2. 关键接口
- 构造:
JWT(expiresIn, keyPath)JWT(secret, ttlSeconds)
- 配置:
setSecretloadSecretFromFilesetDefaultTTL
- Token:
generateToken(customClaims, ttlSeconds)verifyToken(token, payloadJson)parseClaims(token)
- 密码:
encrypt_password(password)verify_password(password, stored_hash)
3. Token 生成流程
generateToken 关键步骤:
- 检查
secret_非空 - 固定头部:
{"alg":"HS256","typ":"JWT"} - 生成
iat(签发时间) - 计算
exp(若 TTL > 0) - 构建 payload(通过
JsonValue序列化) base64UrlEncode(header) + "." + base64UrlEncode(payload)- 用
HMAC-SHA256(signingInput, secret)生成签名 - 拼接三段 token
4. Token 验证流程
verifyToken 执行:
- 检查
secret_ splitToken拆成 3 段- 重新计算签名并比较
- 解码 payload
- 提取
exp并校验过期 - 可选回写
payloadJson
5. 编码与哈希实现细节
base64UrlEncode/base64UrlDecode:URL 安全 Base64 变体sha256:自实现 SHA-256 压缩流程hmacSha256:标准 ipad/opad 组合
6. 密码哈希实现
encrypt_password 逻辑:
- 生成随机盐(16字节)
- 迭代 100000 次 HMAC-SHA256
- 返回格式:
salt_hex:iterations:hash_hex
verify_password:
- 解析上述格式
- 用同盐值与迭代次数重算
- 常量时间比较
constant_time_compare
7. 实现优点
- 不依赖外部加密库,部署简单
- JWT + 密码哈希打包在一个模块,便于业务接入
- 提供
parseClaims方便业务直接读取声明
8. 已知风险与改进建议
verifyToken里签名比较目前使用普通!=,未调用常量时间比较- 建议改为
constant_time_compare(expected, actual)
- 建议改为
- 自实现密码学长期维护成本较高
- 建议引入成熟库(OpenSSL/libsodium)并保留统一接口层
getInstance()默认构造可能得到空密钥实例- 建议强制初始化流程,避免业务误用
9. 面试可讲的取舍
“当前实现优先可控和跨平台一致性,便于理解底层过程;生产场景会优先接入成熟加密库,并补齐密钥轮换、算法升级和安全审计。”