--- tags: [test/review, auth, pattern, oauth2] create time: 2026-08-09 12:00 --- # OAuth2 与 JWT — 测试题 ## 概述 本测试覆盖 OAuth2 四种授权模式、JWT 结构(Header/Payload/Signature)、HS256 vs RS256、Refresh Token 轮换机制以及 Token 黑名单策略。共 10 道题目(6 选择 + 3 填空 + 1 简答)。 --- ## 一、选择题(6道,由浅入深) > **难度阶梯**: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景 ### Q1(基础)— 考察定义层面 OAuth2 中目前最推荐的安全授权模式是: A. Authorization Code + PKCE B. Implicit C. Password D. Client Credentials ### Q2(基础)→ 以下哪种 OAuth2 授权模式**不需要用户参与**? A. Authorization Code B. Implicit C. Password D. Client Credentials ### Q3(进阶)— 核心原理 JWT 的 Header + Payload → Signature 的计算过程是: A. base64UrlEncode(header) + "." + base64UrlEncode(payload),然后用 secret 或私钥签名 B. 直接将三个部分拼接后编码为 Base64 C. 将 payload 用私钥加密 D. 将 header 和 payload 分别签名后拼接 ### Q4(进阶)— 比较/辨析 微服务架构为什么推荐 RS256(非对称)而不是 HS256(对称)? A. RS256 性能更好 B. 每个微服务只需验证公钥而不需要持有签发私钥,即使某个服务被攻陷也无法伪造其他服务的 token C. HS256 不支持自定义 claim D. RS256 不需要设置 exp 过期时间 ### Q5(深入)— 场景推理 在 Refresh Token 轮换机制中,如果同一个 Refresh Token RT1 被使用了两次(第一次正常刷新生成了 RT2+AT2,第二次攻击者重放了旧的 RT1),第二次的处理策略是什么? A. 正常刷新生成新的 RT3+AT3 B. 忽略重复请求返回之前的 AT2 C. 级联销毁该用户的所有 token 并要求重新登录 D. 只冻结 RT1 但不影响其他 token ### Q6(深入)— 源码级/边界场景 关于 JWT 的使用,以下哪个做法是错误的? A. Access Token 设置为短生命周期(如 5~15 分钟) B. Refresh Token 存放在 HttpOnly Cookie 而非 localStorage C. 把用户密码放在 JWT payload 中以方便验签时读取 D. RS256 模式下验证方只用公钥本地验签零网络调用 --- ## 二、填空题(3道) ### F1 — 填空1 JWT 标准保留声明(Registered Claims)包括六个:`iss`(_____)、`sub`(主题/用户标识)、`aud`(_____)、`exp`(过期时间)、`iat`(签发时间)、`jti`(JWT ID 唯一标识支持撤销)。请填写其中两个中文名称。 > **提示**: iss = Issuer, aud = Audience。 ### F2 — 填空2 Token 管理常用的混合策略是:**短生命周期 Access Token(5 分钟)** + 本地校验(无需网络查询);**Refresh Token 存储在_____**每次刷新做一次性校验;特殊场景下的**黑名单**用于主动登出和密码修改后的批量踢人。 > **提示**: 回忆原文 Token 管理混合策略的描述。 ### F3 — 填空3 PKCE(Proof Key for Code Exchange)通过 `code_verifier` / `code_challenge` 对替代 `client_secret`,使 Authorization Code 对所有客户端类型(包括无法安全存储 client_secret 的_____ App 和 SPA)都是安全的。 > **提示**: PKCE 解决的问题是让没有秘密的客户端也能安全使用 Authorization Code 模式。 --- ## 三、简答题(1道) ### S1 面试官问:"某系统的认证架构如下:前端收到 AT(Access Token)存在 localStorage 中,后端用 HS256 签名,RT(Refresh Token)也放在 localStorage 里每次刷新再生成新 RT。请指出这个设计中的至少三个安全问题并给出改进方案。" > **答题框架提示**: > 1. Token 存储位置的安全性 > 2. 签名算法的选择 > 3. Refresh Token 的轮换安全性 > 4. 补充:是否还有其他可改进之处 --- ## 参考答案与解析 ### 选择题答案 | 题号 | 正确答案 | 解析 | |------|---------|------| | Q1 | A | Authorization Code + PKCE 是当前最推荐的方案。Code 在后端交换(浏览器拿不到 token),PKCE 进一步解决了 SPA/Mobile 无法保护 client_secret 的问题。Implicit 已废弃,Password 仅限第一方应用。 | | Q2 | D | Client Credentials 没有用户参与——客户端用自己的身份(client_id + client_secret)申请令牌。典型场景:后台定时任务、微服务间内部调用、CI/CD 流水线。 | | Q3 | A | 标准的 JWT 签名计算流程:base64UrlEncode(header) + "." + base64UrlEncode(payload),然后 HMACSHA256 或用 RSA 私钥签名。Base64 是可逆编码不是加密。 | | Q4 | B | RS256 的核心优势是每个服务只需公钥就能验证——即使某台服务被攻陷,攻击者只有公钥无法伪造 token(因为签名需要私钥)。HS256 要求所有服务共享同一个密钥,任何一台泄漏导致全局崩溃。 | | Q5 | C | 原文明确:如果同一个 Refresh Token 出现两次,第二次判定为窃听攻击,同时**级联销毁该用户的所有 token 并要求重新登录**。这是最安全的防御策略。 | | Q6 | C | JWT 只是 Base64 编码而非加密,任何人都可以解码阅读 payload。**绝对不要把敏感信息放在 JWT payload 中**。如果需要保密应使用 JWE(加密型 JWT)。 | ### 填空题答案 | 题号 | 答案 | 解析 | |------|------|------| | F1 | `Issuer(签发者)`;`Audience(接收方)` | 六大标准声明中,iss 标识谁签发的,aud 标识谁应该接收这个 token。配合 exp(过期时间)实现完整的生命周期控制。jti 提供撤销能力。 | | F2 | `Redis` | 混合策略的三段论:① 短 AT 本地验证;② RT 存 Redis 单次校验防重放;③ 黑名单应对特殊情况。这种组合兼顾性能和安全性。 | | F3 | `移动`(或"Mobile") | RFC 7636 定义的 PKCE 让 Authorization Code 模式适用于所有客户端类型——不仅是传统的有后端的服务,也包括无法安全存储 client_secret 的移动 App 和 SPA。 | ### 简答题参考答案 S1:**参考答案要点**: 1. **localStorage 安全风险**:AT 和 RT 都存在 localStorage 中容易被 XSS 窃取。改进:AT 可以放在内存变量中(页面刷新需重新登录),RT 必须放在 HttpOnly Cookie(JS 无法读取)。 2. **HS256 密钥泄露风险**:所有微服务共享同一个 secret,一旦某台服务器被攻陷全局信任崩溃。改进:改用 RS256,各服务用不同公钥独立验证。 3. **Refresh Token 未旋转**:虽然每次生成新 RT,但如果缺少"同一 RT 出现两次触发级联吊销"的检测,攻击者可以用旧 RT 无限次重放而不会被发现。改进:增加 RT 消费记录检查逻辑。 4. **补充 - 缺少 state 防护**:Authorization Code 回调时未校验 state 参数可能导致 CSRF 攻击。改进:生成随机 state 存 cookie 中,回调时比对。 5. **补充 - 无 token 黑名单**:用户登出或改密码后无法立即吊销已发出的 AT。改进:引入 Redis 黑名单或利用短生命周期 + RT 强制重新认证缓解。 **评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖全部要点。 ## 关联笔记 - [[RBAC 权限模型]]