JWT 鉴权
CHAPTER 09

JWT 鉴权

2 分钟阅读 · 492 字

对应文件:

  • 接口:include/jwt.h
  • 实现:src/jwt.cpp

1. 模块定位

该模块实现:

  • JWT 生成与验证(HS256)
  • claims 解析
  • TTL 解析(如 30m、7d)
  • 密码哈希与验证(PBKDF2 风格循环 HMAC-SHA256)

2. 关键接口

  • 构造:
    • JWT(expiresIn, keyPath)
    • JWT(secret, ttlSeconds)
  • 配置:
    • setSecret
    • loadSecretFromFile
    • setDefaultTTL
  • Token:
    • generateToken(customClaims, ttlSeconds)
    • verifyToken(token, payloadJson)
    • parseClaims(token)
  • 密码:
    • encrypt_password(password)
    • verify_password(password, stored_hash)

3. Token 生成流程

generateToken 关键步骤:

  1. 检查 secret_ 非空
  2. 固定头部:{"alg":"HS256","typ":"JWT"}
  3. 生成 iat(签发时间)
  4. 计算 exp(若 TTL > 0)
  5. 构建 payload(通过 JsonValue 序列化)
  6. base64UrlEncode(header) + "." + base64UrlEncode(payload)
  7. 用 HMAC-SHA256(signingInput, secret) 生成签名
  8. 拼接三段 token

4. Token 验证流程

verifyToken 执行:

  1. 检查 secret_
  2. splitToken 拆成 3 段
  3. 重新计算签名并比较
  4. 解码 payload
  5. 提取 exp 并校验过期
  6. 可选回写 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. 面试可讲的取舍

“当前实现优先可控和跨平台一致性,便于理解底层过程;生产场景会优先接入成熟加密库,并补齐密钥轮换、算法升级和安全审计。”

全部章节