关于 XMLHttpRequest 中的 withCredentials 属性

date
Feb 15, 2023
slug
xmlhttprequest-with-credentials
status
Published
tags
HTTP
type
Post
lang
summary
最近在尝试使用 mock 工具 mockoon 时产生的跨域问题,排查过程中又发现新知识了。
最近在尝试使用 mock 工具 mockoon 时产生的跨域问题。接口已经在 Res Body 配置:Access-Control-Allow-Origin: *,但还是产生了跨域问题,研究了半天发现是 XMLHttpRequest.withCredentials 导致的,之前完全不了解这个 API,简单记录一下。

原因

XMLHttpRequest.withCredentials 配置为 true 时,Access-Control-Allow-Origin: * 的配置是不被接受的,因为与 credentials 的设计相悖。可以参考此文档:Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’

解决

Res Headers 中,Access-Control-Allow-Origin 需要指定域名。同时需要配置 Access-Control-Allow-Credentials: true
当请求的 credentials 模式(Request.credentials)为 include 时,浏览器仅在响应标头 Access-Control-Allow-Credentials 的值为 true 的情况下将响应暴露给前端的 JavaScript 代码。

其他

关于 Access-Control-Allow-Credentials

Access-Control-Allow-Credentials 响应头用于在请求要求包含 credentials(Request.credentials 的值为 include)时,告知浏览器是否可以将对请求的响应暴露给前端 JavaScript 代码。

关于 XMLHttpRequest.withCredentials

XMLHttpRequest.withCredentials 属性是一个 Boolean 类型,它指示了是否该使用类似 cookie、Authorization Headers (头部授权) 或者 TLS 客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。在同一个站点下使用 withCredentials 属性是无效的。
此外,这个标志还用于指示是否需要忽略响应中的 cookie。默认值是 false。如果在发送来自其它域的 XMLHttpRequest 请求之前,未设置withCredentials 为 true,那么就不能为它自己的域设置 cookie 值。而通过设置 withCredentials 为 true 获得的第三方 cookie,将依旧遵循同源策略,因此不能被发起请求的脚本通过 document.cookie 或者响应标头访问。
  • 配置 XMLHttpRequest.withCredentials 永远不会影响到同源请求;
  • 默认值是 false

配置了 XMLHttpRequest.withCredentials 为 true 后,为什么还是无法将 cookie 携带到三方页面?

配置了 Credentials 为 true 后,为什么还是无法将 cookie 携带到三方页面?
主要是因为以前 Cookie 中的 SameSite 属性 None 是默认值,但最近的浏览器版本将 Lax 作为默认值,以便对某些类型的跨站请求伪造(CSRF)攻击具有相当强的防御能力。

为什么要有 XMLHttpRequest.withCredentials?

出于安全考虑,游览器的跨域请求默认是无法携带 Cookie 的,这就避免了 CSRF 上的问题。攻击者伪造的地址在受害者点击后,不会直接携带 Cookie 到服务端。

© CC BY-SAJin 2019 - 2023

Powered by Vercel & Notion