Access-Control-Allow-Credentials
用法
跨源请求默认会排除凭据,例如 Cookie、Authorization 头和 TLS 客户端证书。当客户端将凭据模式设置为 include 时,服务器必须返回值为 true 的 Access-Control-Allow-Credentials,浏览器才会将响应体和响应头暴露给发起调用的脚本。
在预检交互过程中,该头表明实际请求是否被允许携带凭据。如果预检响应省略了该头或设置了 true 以外的值,浏览器会完全屏蔽带凭据的请求。
对于简单的 CORS 请求(那些无需预检步骤的请求,例如基本的 GET),浏览器在收到响应后仍会检查该头。如果该头缺失,响应会被静默丢弃,永远不会到达发起调用的代码。
注意
当携带凭据时,Access-Control-Allow-Origin 头必须指定一个明确的源。带凭据的请求不允许使用通配符 *。
true
唯一有效的值。将该头设为 true 会告诉浏览器在存在凭据时暴露响应。
Access-Control-Allow-Credentials: true
省略该头或发送任何其他值的效果相同:浏览器会将响应视为不带凭据,并对 JavaScript 隐藏响应体。
示例
前端应用发送一个带凭据的跨源 fetch。服务器以凭据头、明确的源以及 Vary 指令作为响应,以便缓存区分不同的源。
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Vary: Origin
在针对带凭据 POST 请求的预检过程中,服务器同时确认允许的方法和对凭据的支持。
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 3600
Vary: Origin
故障排查
当 CORS 链中的任何环节配置有误时,带凭据的跨源请求都会静默失败。
尽管服务器返回了 Access-Control-Allow-Credentials: true,跨源请求仍未发送 Cookie。客户端代码必须主动选择发送凭据。在 Fetch API 中,在请求选项里传入 credentials: ‘include’。在 XMLHttpRequest 中,在调用 send() 之前设置 withCredentials = true。没有这个标志,浏览器会从跨源请求中剥离 Cookie 和 Authorization 头,无论服务器如何响应。
控制台显示”Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.”。当 Access-Control-Allow-Credentials 为 true 时,Access-Control-Allow-Origin 头必须包含一个明确的源。读取传入的 Origin 头,对照允许列表校验其值,将匹配到的源回显回去,并在响应中加入 Vary: Origin。同样的规则也适用于 Access-Control-Allow-Headers 和 Access-Control-Allow-Methods:在带凭据的请求中,这些头里的通配符会被当作字面字符串处理。
fetch() 调用缺少 credentials: ‘include’。Fetch API 默认为 credentials: ‘same-origin’,这会在跨源请求中排除凭据。请显式传入 { credentials: ‘include’ }。在 DevTools 的 Network 标签中检查请求头。如果发出的请求中缺少 Cookie 头,说明客户端没有主动选择加入。
XMLHttpRequest 缺少 withCredentials = true。与 Fetch API 类似,除非将 withCredentials 设为 true,否则 XMLHttpRequest 不会跨源发送 Cookie。该属性必须在调用 xhr.open() 或 xhr.send() 之前设置。Axios 等库将其暴露为请求配置中的 { withCredentials: true }。
SameSite Cookie 属性阻止跨源投递。现代浏览器在未设置 SameSite 属性时默认为 SameSite=Lax。Lax Cookie 不会在跨源 POST 或子资源请求中发送。对必须跨源传输的 Cookie 设置 SameSite=None 和 Secure。在 DevTools 的 Application 下验证该属性。
Cookie。没有 Secure,浏览器会完全拒绝 SameSite=None 的 Cookie。
第三方 Cookie 淘汰阻止凭据传输。Chrome 及其他浏览器正在限制第三方 Cookie。依赖由不同域设置的 Cookie 的跨源请求面临越来越多的失效问题。在可能的情况下,改用基于 token 的认证并使用 Authorization 头,或采用 Storage Access API 来显式请求 Cookie 访问权限。在 Chrome 中启用”Third-party cookie phaseout”标志进行测试,以便在正式上线前暴露问题。