Skip to content

一、初始登录阶段 ​

  1. 用户提交登录凭证:用户在客户端输入用户名、密码等身份验证信息,通过HTTPS协议发送至服务端认证接口。
  2. 服务端验证身份:服务端接收请求后,对用户提交的凭证进行校验,包括账号密码匹配度、账号状态(是否禁用、锁定)等。
  3. 生成双Token:验证通过后,服务端生成两类Token:
    • Access Token:采用JWT格式,包含用户ID、角色权限、过期时间(通常设置为15-30分钟)等基础信息,通过签名算法加密后生成。
      • Refresh Token:生成随机字符串或加密令牌,有效期设置为7-30天,仅关联用户ID,不包含敏感权限信息。
  4. 返回Token至客户端:服务端将Access Token直接返回至客户端,同时将Refresh Token存储在服务端Redis或数据库中,并通过HttpOnly、Secure属性的Cookie返回给客户端,禁止前端JS读取,防范XSS攻击。
  5. 客户端存储Token:客户端将Access Token存储在内存或LocalStorage中,用于后续接口请求;Refresh Token由浏览器自动管理在Cookie中,无需前端手动操作。

二、正常资源访问阶段 ​

  1. 客户端发起请求:客户端每次调用受保护的API接口时,自动在请求头的Authorization字段中携带Bearer ${Access Token}。
  2. 服务端验证Access Token:服务端接收请求后,首先解析并验证Access Token的有效性,包括签名是否合法、是否过期、权限是否匹配等。
  3. 返回资源或错误信息:
    • 验证通过:服务端处理业务逻辑,返回接口数据及200状态码。
    • 验证失败:若Access Token过期、签名无效或权限不足,服务端返回401 Unauthorized状态码,并在响应头中携带Refresh-Token-Required标识,提示客户端需要刷新Token。

三、Token自动刷新阶段 ​

  1. 客户端触发刷新逻辑:客户端捕获到401状态码及Refresh-Token-Required标识后,自动触发Token刷新流程,避免用户感知。
  2. 客户端发送刷新请求:客户端向服务端刷新接口发送POST请求,浏览器自动携带存储在Cookie中的Refresh Token,无需前端手动添加。
  3. 服务端验证Refresh Token:服务端从Redis或数据库中查询该Refresh Token的记录,验证其是否存在、是否过期、是否与用户ID匹配,同时检查是否超过绝对会话上限(如设置30天,即使Refresh Token未过期,也需强制重新登录)。
  4. 刷新成功处理:
    • 服务端生成新的Access Token和Refresh Token,新Refresh Token覆盖原记录存储在服务端,并更新Cookie中的Refresh Token。
    • 服务端将新的Access Token返回至客户端,同时在响应头中携带新的Token过期时间。
    • 客户端更新本地存储的Access Token,自动重试之前失败的接口请求,将请求头中的Token替换为新的Access Token。
  5. 刷新失败处理:
    • 若Refresh Token过期、无效或超过绝对会话上限,服务端返回401 Unauthorized状态码,并携带Re-Login-Required标识。
    • 客户端清理本地存储的Access Token,跳转到登录页面,提示用户重新登录。

四、用户登出阶段 ​

  1. 客户端发起登出请求:用户在客户端点击登出按钮,客户端向服务端登出接口发送请求。
  2. 服务端清理Token记录:服务端接收到登出请求后,从Redis或数据库中删除该用户对应的Refresh Token记录,使其立即失效。
  3. 客户端清理状态:客户端清空本地存储的Access Token,同时浏览器自动清除Refresh Token对应的Cookie,完成登出流程。

五、异常场景处理 ​

  1. Access Token泄露:由于Access Token有效期短,攻击者仅能在有限时间内访问资源,服务端可通过监控异常请求频率,及时触发Refresh Token失效,强制用户重新登录。
  2. Refresh Token泄露:攻击者无法直接使用Refresh Token访问业务资源,仅能用于刷新Access Token。服务端可通过绑定用户IP、设备指纹等信息,验证Refresh Token使用环境的一致性,发现异常立即失效。
  3. 并发刷新请求:当多个请求同时触发401状态码时,客户端通过全局锁机制(如isRefreshing变量)确保仅发起一次刷新请求,避免重复生成Token。