HTTPQUERY
English

Authorization

用法

Authorization 请求头用于获取对受保护资源的访问权限,通常在客户端被告知访问受限后发送。例如,在收到服务器返回的、包含 WWW-Authenticate 头的 401 Unauthorized HTTP 响应后,客户端便以这种方式提交凭据。

注意

当请求被重定向到不同的源时,浏览器会剥离 Authorization 头。这可以在重定向指向第三方服务器时防止凭据泄露。该行为在 WHATWG Fetch 标准中定义,并被所有现代浏览器支持。依赖跨源重定向中 Authorization 头的应用需要在最终目的地处理重新认证。curl、Python Requests 和 Go 的 HTTP 客户端等工具都遵循相同的约定。

authentication-scheme

authentication-scheme 是一个必需的指令,可附带可选的方案特定参数。方案定义了凭据的编码方法。常见做法包括 Basic、Bearer、Digest 和 Negotiate。

示例

在这个例子中,客户端使用 Basic 认证方案。作为必需参数,凭据是经过 base64 编码的 username:password 组合。

Authorization: Basic RXhhbXBsZTphaQ==

Bearer token 常用于 OAuth 2.0 API。该 token 是一个不透明字符串,或是由授权服务器签发的已签名 JWT。

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

故障排查

认证失败通常表现为意外的 401 响应或凭据被静默丢弃。

跨源重定向时凭据被剥离。当请求重定向到不同的源时,浏览器和 HTTP 客户端会移除 Authorization 头。修复方法是直接向最终目的地发送凭据,或在重定向完成后重新认证。用 curl -L -v 检查重定向链,以确认头在何处消失。

Basic 认证中的 Base64 编码错误。编码后的字符串必须恰好包含一个分隔用户名和密码的冒号。缺少冒号或双重编码的值会产生服务器拒绝的乱码 token。用 echo -n “user:pass” | base64 验证原始值,并与请求中发送的头值比对。

Bearer token 已过期或格式错误。token 携带过期声明,服务器会以 401 拒绝已过期的 token。在 jwt.io 上或用 echo "" | base64 -d 解码 JWT,以检查 exp 字段。token 刷新逻辑必须在 token 过期之前运行,而不是在服务器拒绝请求之后。

当服务器省略 WWW-Authenticate 时出现 401 循环。服务器返回 401 却不包含 WWW-Authenticate 头,使客户端无法得知预期的方案。用 curl -I https://example.re/resource 检查响应头,并确认服务器配置包含了该头。在 nginx 中,auth_basic 指令会自动添加该头。自定义后端需要显式设置该头。

CORS 预检阻止 Authorization 头。携带 Authorization 的跨源请求会触发预检 OPTIONS 请求。服务器必须在预检中以 Access-Control-Allow-Headers: Authorization 作答。缺失或不正确的值会导致浏览器在发送凭据之前就阻止请求。DevTools 的 Network 标签会将预检显示为一条独立的 OPTIONS 条目。

curl 将凭据发送到了错误的端点。运行 curl -H “Authorization: Bearer …” 时加上 -L 会跟随重定向,但在跨源跳转时会剥离该头。使用不带 -L 的 curl -v 将头发送到确切的端点,或传入 —location-trusted 以在重定向间强制转发凭据(仅在受信任的域名上谨慎使用)。

Basic 对比 Bearer

Basic 和 Bearer 是两种最常见的认证方案,服务于不同的使用场景。

Basic 在每个请求上发送经过 Base64 编码的 username:password 组合。该编码可轻易逆向,因此必须使用 HTTPS。凭据是静态的且与用户账户绑定,所以一旦密码泄露就需要更改密码本身。Basic 适用于内部工具和简单的集成场景,在这些场景中引入 token 管理会带来不必要的复杂性。

Bearer 使用由授权服务器签发的不透明 token(通常为 JWT)。token 会过期、携带作用域权限,并且可以在不更改底层密码的情况下被撤销。Bearer 是 API 和 OAuth 2.0 流程的标准机制。被窃取的 token 具有有限的生命周期和有限的作用域,与泄露的密码相比,减小了影响范围。

两种方案都在头值中以明文传输凭据。二者本身都不提供加密。无论选择哪种方案,都需要 HTTPS。

一个使用 Fetch API、带 Bearer token 的跨源 API 请求。

fetch('https://api.example.re/data', {
  headers: {
    'Authorization': 'Bearer eyJhbGci...'
  }
})