1) 【一句话结论】采用基于JWT的无状态鉴权架构,结合短生命周期访问Token(含时间戳+nonce防重放)与长生命周期刷新Token(加密存储防窃取),通过Redis缓存减少数据库查询,集成MFA和Cookie安全属性,有效缓解重放攻击、会话劫持,平衡安全与性能。
2) 【原理/概念讲解】老师会解释核心概念:
- JWT加密机制:Payload(用户名、权限等)用RSA非对称加密,密钥由服务端管理,客户端仅存储加密后的密文,防止中间人窃取。签名算法用RS256(RSA+SHA-256),密钥长度至少2048位。
- Token类型设计:
- 访问Token(Access Token):短生命周期(如15分钟),存储在客户端localStorage,Payload含时间戳(iat)、随机nonce(防重放),用于访问资源。
- 刷新Token(Refresh Token):长生命周期(如1小时),存储在HttpOnly Cookie中,加密存储(如AES-256),用于刷新访问Token。
- 重放攻击防御:访问Token的Payload加入时间戳(iat)和nonce,服务端验证时检查时间戳是否在有效范围内(如5分钟内),nonce是否唯一,防止攻击者重放旧请求。
- 会话劫持防护:刷新Token设置HttpOnly(防止前端脚本窃取)、Secure(仅HTTPS传输)、SameSite=Strict(严格模式,防止CSRF),同时JWT签名用RSA密钥,防止篡改。
- 多因素认证(MFA):登录流程中,用户输入密码后,系统发送短信验证码,用户输入验证码正确后,再生成访问Token,增加安全层级。
- 缓存优化:Redis缓存用户Token(key为Token值,value为用户信息加密密文+过期时间,与JWT相同)和用户基本信息(key为用户ID,value为用户名等),验证Token时先查Redis,若不存在再查数据库,减少数据库压力。
3) 【对比与适用场景】
| 对比项 | 访问Token(Access Token) | 刷新Token(Refresh Token) |
|---|
| 定义 | 用于访问资源的凭证 | 用于刷新访问Token的凭证 |
| 生命周期 | 短(如15分钟) | 长(如1小时) |
| 存储位置 | 客户端localStorage | Cookie(HttpOnly) |
| 安全属性 | 无需特殊属性(但需签名) | HttpOnly、Secure、SameSite |
| 功能 | 访问资源(如API) | 刷新访问Token |
| 有效期依据 | 用户活跃度(15分钟) | 业务需求(1小时) |
| 注意点 | 防重放(时间戳+nonce) | 防窃取(Cookie安全) |
4) 【示例】
用户登录流程(含MFA):
- 用户发送POST请求
/login,包含用户名、密码、手机号。
- 服务端验证用户名密码,若正确,发送短信验证码到用户手机。
- 用户输入验证码,服务端验证验证码正确后,生成访问Token(Payload加密后签名,含iat=当前时间,nonce=随机数,exp=15分钟后)和刷新Token(加密存储,过期1小时),返回给客户端。
- 客户端存储访问Token(localStorage)和刷新Token(Cookie,HttpOnly)。
- 后续请求(如
/api/profile)携带Authorization头:Bearer eyJ...。
- 若访问Token过期(exp时间到),客户端发送POST请求
/refresh_token,携带刷新Token(Cookie中),服务端验证后生成新的访问Token和刷新Token,返回给客户端。
5) 【面试口播版答案】
面试官您好,我来设计一个安全且高效的用户登录鉴权系统。核心思路是采用基于JWT的无状态架构,结合短生命周期访问Token(防重放)与长生命周期刷新Token(安全存储),通过Redis缓存减少数据库查询,并集成多因素认证(MFA)和Cookie安全属性,全面缓解重放攻击、会话劫持。
首先,系统架构分为前端、网关、业务服务、Redis缓存和MySQL数据库。用户登录后,通过网关发送请求到业务服务,验证用户名密码,生成加密的JWT(Payload含用户信息,用RSA加密)和刷新Token(存储在HttpOnly Cookie中)。后续请求携带访问Token,网关验证签名和过期时间,若过期则触发刷新流程。
关键组件包括:用户认证服务(处理登录、密码校验)、Token生成服务(生成加密JWT和刷新Token)、Token验证服务(验证签名和过期)、缓存服务(Redis存储Token和用户信息)、数据库服务(存储用户和刷新Token)。安全措施方面,访问Token的Payload加入时间戳和随机nonce,防止重放;刷新Token用Cookie的HttpOnly、Secure、SameSite=Strict,避免被窃取;登录流程中集成短信验证码(MFA),增加安全层级。
性能优化上,验证Token时先查Redis缓存,若不存在再查数据库,减少数据库压力。同时,设置合理的过期时间:访问Token15分钟(用户活跃时),刷新Token1小时(用户不活跃时),平衡安全与用户体验。
总结来说,这个系统通过加密敏感信息、缓存优化、MFA和Cookie安全,有效提升了安全性和性能,能应对高并发场景下的重放攻击和会话劫持。
6) 【追问清单】
- Token泄露后如何处理? 回答要点:立即生成新的访问Token和刷新Token,清除Redis缓存中的旧Token,并通知用户更换密码。
- 如何处理用户长时间不活跃? 回答要点:访问Token设置短有效期(如15分钟),超时后用户需重新登录;刷新Token设置长有效期(如1小时),超时后需重新获取新Token。
- 多因素认证(MFA)具体步骤? 回答要点:用户输入密码后,系统发送手机验证码,用户输入验证码正确后,再生成访问Token,MFA失败则拒绝登录。
- Redis缓存如何防穿透和雪崩? 回答要点:使用布隆过滤器过滤无效Token,限流控制请求频率,避免缓存穿透和雪崩。
- 跨服务鉴权如何实现? 回答要点:通过JWT的Payload传递用户信息,各服务验证Token后即可获取用户信息,无需额外数据库查询。
7) 【常见坑/雷区】
- JWT Payload未加密:雷区:敏感信息(如用户名、权限)未加密,导致中间人窃取。
- 刷新Token存储不安全:雷区:未设置HttpOnly、Secure或SameSite,导致前端脚本窃取。
- 未防重放攻击:雷区:访问Token未加入时间戳+nonce,攻击者可重放旧请求。
- 缓存未设置过期时间:雷区:Token未过期但用户已登出,攻击者仍可使用旧Token。
- JWT有效期设置不合理:雷区:访问Token有效期过长(如1小时),导致安全风险;或过短(如5分钟),影响用户体验。