401 与 403 的分界线
两个码都在说「你没通过」,但卡的位置不同:401 表示没有完成认证,服务端在问「你是谁」,客户端应当带上或刷新凭证后重试,响应必须带 WWW-Authenticate 说明认证方式;403 表示认证已经通过、身份明确,但这个身份没有被授权做这件事,重试没有意义。混淆两者会直接引发客户端无限重登或权限问题被长期忽略。
基本信息
| 401 | 认证问题:缺少凭证、凭证无效或已过期;响应必须带 WWW-Authenticate |
|---|---|
| 403 | 授权问题:凭证有效但被拒绝;不应再向客户端索要认证 |
| 常见混淆 | 把 403 写成 401,客户端会不断跳登录或刷新令牌 |
| 责任侧 | 401 通常是调用方与令牌链路,403 通常是权限模型与访问策略 |
判断流程
| 现象 | 判定 | 处理方向 |
|---|---|---|
| 不带令牌访问受保护接口 | 401 | 客户端跳登录或刷新令牌后重试 |
| 令牌有效但角色权限不足 | 403 | 申请授权并核对权限模型 |
| 令牌有效、权限也正常仍然 403 | 403 | 检查 IP 白名单、WAF 规则与地域策略 |
| 令牌已过期 | 401 | 刷新令牌或重新登录 |
| 网关统一把所有失败都改成 401 | 误判 | 移动端刷新逻辑会死循环,应在网关侧区分 |
验证你的接口行为
验证你的接口行为
curl -si https://api.example.com/me | head -1 # 无凭证:期望 401 并带 WWW-Authenticate
curl -si -H 'Authorization: Bearer INVALID' https://api.example.com/me | head -1 # 无效凭证:期望 401
curl -si -H 'Authorization: Bearer 有效但无权限' https://api.example.com/admin | head -1 # 期望 403
curl -si -H 'Authorization: Bearer 过期令牌' https://api.example.com/me | head -1 # 期望 401401 的中文常译作未授权,这是历史遗留的误导:它实际是未认证。真正意义上的未授权在 HTTP 语义中对应 403。
令牌体系里还有一层细节:访问令牌过期返回 401 属于正常流程,但刷新令牌本身也失效时同样是 401。客户端应限制刷新次数并在刷新失败后跳登录,否则一个 401 会引出成串的刷新请求。