带 credentials 的 CORS 请求

Credentials 与 CORS

Credentials(凭证) 可以是 cookies, authorization headers 或 TLS client certificates。
CORS 请求默认不发送 Credentials。

如何让 CORS 请求发送 Credentials?

如果要让带 credentials 的 CORS 请求成功,前后端都需要配置。否则,即使服务器同意发送 Cookie,浏览器也不会发送。或者,服务器要求设置 Cookie,浏览器也不会处理。

Cookie 依然遵循同源政策,只有用服务器域名设置的 Cookie 才会上传,其他域名的 Cookie 并不会上传

配置

后端配置:
Access-Control-Allow-Credentials header;
前端配置:
XHR 配置 withCredentials 或 Fetch request 配置 credentials;

Access-Control-Allow-Credentials

它的值是一个布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中。设为true,即表示服务器明确许可,Cookie 可以包含在请求中,一起发给服务器。
如果服务器不要浏览器发送 Cookie,删除该字段即可。

Request.credentials

credentialsRequest接口的只读属性,用于表示用户代理是否应该在跨域请求的情况下从其他域发送 cookies。有三个可选值:

  • omit: 从不发送cookies。
  • same-origin: 只有当URL与响应脚本同源才发送 cookies、 HTTP Basic authentication 等验证信息。
  • include: 不论是不是跨域的请求, 总是发送请求资源域在本地的 cookies、 HTTP Basic authentication 等验证信息。

XMLHttpRequest.withCredentials

withCredentials是一个Boolean类型,如果是 true, 执行跨域请求时会带上 Credentials,否则不会携带。默认值是false。

  • 如果在发送来自其他域的XMLHttpRequest请求之前,未设置withCredentials 为true,那么就不能为它自己的域设置cookie值。
  • 通过设置withCredentials 为 true 获得的第三方 cookies,将会依旧享受同源策略,不能被通过 document.cookie 或者从头部相应请求的脚本等访问。
  • 在同一个站点下使用withCredentials属性是无效的。它永远不会影响到同源请求。

例子

后端允许 credentials:

Access-Control-Allow-Credentials: true

前端使用带 credentials 的 XHR 请求:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

前端使用带 credentials 的 Fetch 请求:

fetch(url, {
  credentials: 'include'
})
当 credentials 是 include 时,Access-Control-Allow-Credentials 必须设置为 true; 当 credentials 是其他值时,可以不设置Access-Control-Allow-Credentials。

设置 credentials: 'include' 不生效

现在设置 credentials 的 Fetch 请求如下:

fetch(url, {
  credentials: 'include'
})

实际出去的请求:

fetch(url, {
  credentials: 'omit'
})

为什么设置的include无效,反而被修改为 omit?
经检查发现,当前页面协议为 http,请求 url 协议是 https,如果两个协议不同,则请求时主动修改 credentials 为 'omit'。


时倾
794 声望2.4k 粉丝

把梦想放在心中


引用和评论

0 条评论