HTTP 401 vs 403:区别、排查顺序与接口设计建议

401 和 403 是最容易被混用的两个状态码。前端看到它们常常只能“跳登录页”,但真实问题可能在 token、权限模型、网关映射甚至缓存层。先把语义用对,排障效率会直接提高。

1. 先记住语义边界

  • 401 Unauthorized:身份还没通过认证,或者认证已失效。
  • 403 Forbidden:身份有效,但没有访问该资源的权限。

一句话:401 先解决“你是谁”,403 再解决“你能做什么”。

2. 401 的高频原因

  • 请求没带 `Authorization` 或 Cookie。
  • token 过期、签名不合法、issuer/audience 不匹配。
  • 网关和应用服务的 token 校验规则不一致。
  • 时钟偏移导致 `nbf/exp` 判断异常。

建议响应里带可读错误码(如 `token_expired`),不要只给“unauthorized”。

3. 403 的高频原因

  • 角色没有对应路由的操作权限。
  • 租户隔离策略命中(跨租户访问)。
  • 资源级 ACL 不通过(如只能访问自己创建的数据)。
  • 风控策略拒绝(IP、地区、设备风险)。

403 的返回应该告诉前端“权限不足”而不是“请重新登录”,避免错误引导用户。

4. 推荐排查顺序(从快到慢)

  1. 确认请求头是否带了认证信息。
  2. 校验 token 有效期、签名和 claims。
  3. 查看鉴权中间件日志是否通过。
  4. 查看权限服务或策略引擎的决策结果。
  5. 排查网关/反向代理是否改写了状态码。

5. 接口设计建议

  • 401 返回 `WWW-Authenticate` 或明确错误码,便于客户端刷新凭证。
  • 403 返回缺失权限标识,便于前端灰掉无权限按钮。
  • 日志里打通 `request_id`、`user_id`、`policy_id`,便于审计追踪。
不要把所有权限问题都塞成 401,否则会制造大量“重复登录无效”的用户体验问题。

把 401/403 语义用准确,前后端联调、客服工单和监控告警都会更清晰。