HTTPQUERY
English

401 Unauthorized

用法

收到 401 Unauthorized 错误时,客户端明白在获准访问所请求的资源之前,需要提供有效的登录凭据。客户端需要先登录,或将凭据作为 HTTP 请求的一部分提供。随请求发送的现有凭据也可能无效。此状态不同于 403 Forbidden,后者告知客户端无论凭据如何该操作都不被允许。

注意

“Unauthorized”(未授权)这一名称在历史上具有误导性。401 表示客户端未通过认证:凭据缺失或无效。已通过认证但缺乏执行所请求操作权限的用户,收到的是 403 Forbidden。这一命名沿用自最初的 HTTP/1.0 规范。

当服务器发送 401 Unauthorized 响应时,会包含 WWW-Authenticate 响应头。它告知客户端允许的授权方法。IANA 维护着一份标准认证方案列表,这些方案在安全性和普及度上各有不同。常见的认证方案:

Basic

以 ID/密码对的形式传输凭据。

Bearer

也称为令牌认证,依赖服务器生成并在登录成功后返回给客户端的安全令牌。客户端在后续请求中发送这些令牌以访问受保护资源。服务器在需要时会包含错误详情:WWW-Authenticate: Bearer error=“invalid_token”, error_description=“Token expired”。

Digest

一种用于对资源请求进行认证的质询-响应协议。

HOBA

HTTP Origin-Bound Authentication 的缩写,该方案无需服务器存储密码,因而能够抵御钓鱼攻击。

Mutual

也称为双向认证,与 Basic 和 Digest 方案类似,区别在于服务器可确保知晓客户端的加密密码。客户端与服务器在继续交互之前会相互认证。

AWS4-HMAC-SHA256

一种向 Amazon Web Services AWS S3 API Reference 提供认证信息的认证算法。

服务器可以在多行或单行逗号分隔中指定多种认证方法。当客户端拥有所需凭据时,会使用 Authorization 请求头发送它们。

SEO 影响

像 Google 这样的搜索引擎不会索引返回 401 Unauthorized 状态的 URL。此前已被索引、如今返回该状态码的 URL 会从搜索结果中移除。返回此状态码的页面不会消耗抓取预算。不要用 401 来减缓 Googlebot 的抓取速度。只有 429 才能降低抓取频率。

示例

客户端请求某个资源,服务器返回 401 Unauthorized,表明该资源受保护。服务器表示同时支持 Basic 和 Mutual 授权。客户端使用 Basic 认证协议,在 Authorization 头中以 username:password 对作出响应。随后服务器传输所请求的资源。

初始请求

GET /documents/tech-news HTTP/1.1
Host: example.com

初始响应

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Documents"
WWW-Authenticate: Mutual

下一次请求,包含 Authorization

GET /documents/tech-news HTTP/1.1
Host: example.com
Authorization: Basic RXhhbXBsZTphaQ==

最终响应

HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 25000

<PDF document included in message body>

如何修复

401 Unauthorized 意味着服务器在授予访问权限之前需要有效的凭据。

检查响应中的 WWW-Authenticate 头。此头指定了期望的认证方案(Basic、Bearer、Digest 等)。使客户端请求与所需方案相匹配。打开浏览器开发者工具,选择 Network 标签页,在 Response Headers 下查找 WWW-Authenticate 条目。

核实凭据。确认用户名和密码、API 密钥或 bearer 令牌是否正确。Authorization 头值中的一个拼写错误或空白字符都会导致拒绝。用 curl -H “Authorization: Bearer ” 单独测试凭据,以排除应用层问题。

确认令牌未过期。Bearer 令牌和会话令牌具有有限的生命周期。在本地调试器中解码 JWT 以检查 exp 声明。通过认证提供方重新生成或刷新访问令牌。

使 Authorization 头格式与方案相匹配。Basic 期望一个 Base64 编码的 username:password 对。Bearer 期望一个原始令牌字符串。格式不正确即使凭据有效也会触发 401。一个常见错误是省略了方案前缀(只发送令牌而没有 Bearer )。

必要时重新生成凭据。轮换 API 密钥,或从授权服务器请求新令牌。被吊销或作废的凭据始终会产生此状态。

清除浏览器缓存和 Cookie。陈旧的会话 Cookie 或缓存的 Authorization 头会与更新后的凭据冲突。清除已存储的数据并重新认证。

检查服务端的认证配置。Apache 的 .htpasswd 文件、nginx 的 auth_basic 指令,以及 .htaccess 的 AuthType 规则都控制着访问。核实凭据文件路径、realm 名称和用户条目是否存在。在 nginx 中:

auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;

在 Apache 中:

AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

核实 OAuth 作用域和受众声明。凭据正确但作用域错误,或 aud 声明与资源服务器不匹配的访问令牌,仍会触发 401。确认该令牌是为目标 API 签发的。

代码参考

.NET

HttpStatusCode.Unauthorized

Rust

http::StatusCode::UNAUTHORIZED

Rails

:unauthorized

Go

http.StatusUnauthorized

Symfony

Response::HTTP_UNAUTHORIZED

Python3.5+

http.HTTPStatus.UNAUTHORIZED

Java

java.net.HttpURLConnection.HTTP_UNAUTHORIZED

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_UNAUTHORIZED

Angular

@angular/common/http/HttpStatusCode.Unauthorized