401 token刷新

2,334 阅读3分钟

HTTP 401状态码表示未授权(Unauthorized) ,属于客户端错误类响应。通俗来说,它告诉用户: “你需要先登录或提供有效凭证,才能访问这个资源” 。它是权限控制中的常见状态码,与403(Forbidden)有本质区别。


HTTP 401状态码的全称是 Unauthorized(未授权),属于客户端错误类响应(4xx状态码)。它表示当前请求因缺少有效身份验证凭证而被服务器拒绝,是Web开发中与权限控制密切相关的关键状态码。


通俗解释

想象你去参加一个VIP会议:

  1. 如果你没有出示入场券 → 对应401 Unauthorized(根本未认证)
  2. 如果你出示了过期的/假的入场券 → 同样触发401
  3. 如果你有有效入场券但试图进入禁止进入的区域 → 对应403 Forbidden(已认证但无权限)

技术细节解析

1. 触发场景示例

场景服务器响应示例
未携带Token访问需要登录的接口HTTP/1.1 401 Unauthorized
Token过期后请求数据WWW-Authenticate: Bearer error="invalid_token"
使用已注销用户的SessionID返回401并清除客户端Cookie

2. 与403 Forbidden的区别

状态码认证状态典型场景
401未通过认证未登录、Token过期、凭证格式错误
403已认证但无权限普通用户尝试访问管理员接口

前端处理方案(基于简历中的Axios案例)

// axios响应拦截器优化版
let isRefreshing = false
let requestsQueue = []

axios.interceptors.response.use(null, async error => {
  if (error.config && error.response?.status === 401) {
    
    // 排除登录接口本身(防止死循环)
    if (error.config.url.includes('/refresh-token')) {
      return redirectToLogin()
    }

    if (!isRefreshing) {
      isRefreshing = true
      try {
        const newToken = await refreshToken()
        store.updateToken(newToken)
        
        // 重试所有积压的请求
        requestsQueue.forEach(cb => cb(newToken))
        requestsQueue = []
        
        // 重试原始请求
        error.config.headers.Authorization = `Bearer ${newToken}`
        return axios(error.config)
      } catch (refreshError) {
        // 刷新Token失败则强制登出
        store.logout()
        window.location.href = '/login?timeout=1'
      } finally {
        isRefreshing = false
      }
    }

    // 将未完成的请求加入队列
    return new Promise(resolve => {
      requestsQueue.push(token => {
        error.config.headers.Authorization = `Bearer ${token}`
        resolve(axios(error.config))
      })
    })
  }
  return Promise.reject(error)
})

关键处理逻辑

  1. 防抖机制:通过isRefreshing标记防止并发刷新
  2. 请求队列:在Token刷新期间暂存后续请求
  3. 错误隔离:对登录/刷新接口做特殊处理
  4. 降级方案:最终失败时跳转登录页并携带错误码

调试技巧

当遇到401问题时,可通过Chrome开发者工具检查:

  1. Network面板:查看请求头是否携带Authorization
  2. Application面板:确认LocalStorage中Token是否过期
  3. Console面板:检查是否有JWT expired等日志

延伸思考:现代JWT方案中,为什么推荐将Token过期时间设置较短(如15分钟)并配合Refresh Token机制?这种设计如何平衡安全性与用户体验?


核心要点

  1. 含义
    • 用户未提供身份凭证(如未登录)
    • 提供的凭证已过期、无效或格式错误
  1. 典型场景
    • 未登录直接访问需要权限的页面
    • Token过期后继续调用接口
    • 请求头中漏传Authorization字段
  1. 与403的区别
401(Unauthorized)403(Forbidden)
含义身份未认证身份已认证,但权限不足
例子没带工牌进公司大门普通员工试图进入高管会议室
  1. 前端处理逻辑
    • 步骤一:拦截401响应 → 跳转登录页
    • 步骤二:尝试自动刷新Token(如有Refresh Token)
    • 步骤三:重试原始请求(若刷新成功)

一句话总结

401是系统的“门禁警报” ——它在说:“请先证明你是合法用户,否则禁止通行!” 🔐