基于 Redis 状态机的 APP 扫码登录深度实现
业务场景背景在企业级 ERP 系统中,网页端(SaaS 管理后台)往往承载着敏感的财务与人事数据。传统的账号密码登录存在被监听或撞库的风险。APP 扫码登录利用手机端已有的安全上下文(如指纹、面容识别后的登录态),为 PC 端提供了一种既快捷又安全的身份穿透方案。
核心交互流程架构
该功能本质上是一个跨端同步的状态机。通过 Redis 作为中转站,将“网页端”、“后端服务”与“移动端”三方串联。
阶段一:凭证初始化(网页端)
网页端加载时调用 getQRToken 接口。
逻辑:生成全局唯一的 qrToken(二维码令牌)。
存储:在 Redis 中存入两个 Key:一个记录 Token 本身,另一个作为“读取状态位”(初始值为 0: 未扫描)。
安全:设置 5 分钟有效期,超时自动失效。
阶段二:身份关联与预授权(移动端扫码)
用户使用已登录的手机 APP 扫描二维码,调用 scanCode 接口。
校验:后端通过 JWTUtils 校验 APP 端的合法性。
信任传递:后端生成一个随机的 preToken(预登录令牌),并更新 Redis 状态为 1: 已扫描,同时关联此 preToken。
返回:将 preToken 返回给手机端,作为后续“确认登录”的唯一凭证。
阶段三:状态探测(网页端轮询)
网页端通过 codeHasBeenRead 接口进行高频轮询(或使用 WebSocket)。
数据解析:后端拆分 Redis 里的字符串(如 1,preToken)。
UI 反馈:网页端一旦拿到状态 1,立即从二维码界面切换为“扫码成功,请在手机确认”的提示状态。
阶段四:最终授权(移动端确认)
用户在手机上点击“确认登录”,调用 goQRLogin 接口。
对暗号:APP 携带 preToken 请求,后端比对 Redis 中的 preToken 是否一致。
暂存信息:比对成功后,将该用户的信息(Users)暂时缓存至 Redis 的临时区域。
阶段五:令牌核发(网页端进入)
网页端发起最后的 checkLogin 调用。
JWT 颁发:后端从 Redis 提取暂存的用户信息,使用 jwtUtils.createJWTWithPrefix 生成 SaaS 平台专属的 JWT。
会话建立:网页端拿到正式令牌,完成登录并进入 ERP 系统主页。
核心代码实现细节
在轮询接口中,通过简单的字符串分割实现高效的状态判定:
1 | Java |
预登录令牌(preToken)的安全价值
preToken 是该方案的安全灵魂。它确保了:
防伪造:只有真实扫过码的手机才能拿到 preToken,攻击者无法通过模拟请求直接进入登录环节。
链路锁定:确保了最后确认登录的手机与显示二维码的网页窗口是一一对应的“信任链路”。
技术亮点与架构思考
无状态化设计:整个过程不依赖 Session,完全由 Redis 维护状态,天然支持集群部署和横向扩展。
多端身份解耦:APP 令牌与 SaaS 令牌前缀不同、有效期不同,实现了移动端与管理后台的权限体系隔离。
防御性编程:在 checkLogin 环节,通过 UUID 和短时效 Redis Key 确保了令牌的一次性,有效防止了重放攻击。
总结
扫码登录不仅是用户体验的优化,更是企业安全策略的延伸。通过 Redis 状态机 + 双重 Token 校验,我们实现了一个低耦合、高可靠的跨端身份认证体系,为 ERP 系统的数据安全构筑了坚固的第一道防线。
负责了 ERP 系统的跨端统一身份认证中心。重点攻克了扫码登录过程中三方状态同步的问题,通过设计一套基于 Redis 的双令牌(qrToken/preToken)确认机制,解决了跨设备信任传递的安全难题。该方案不仅提升了 HR 用户的办公效率,还通过无状态 JWT 颁发机制支撑了系统的高并发访问。”