cookies - 无法让 axios 在跨域请求中包含来自 cookie 的 CSRF 令牌
问题描述
免责声明- 我在 stackoverflow 上查看了很多类似的问题。
我有一个在“https://api.website.com”上运行的后端和一个在“https://admin.website.com”上运行的前端后端的 CORS 策略设置如下:
appCorsResourcePolicy = CorsResourcePolicy {
corsOrigins = Just (["http://localhost:8082", "https://admin.website.com"], True)
, corsMethods = ["OPTIONS", "GET", "PUT", "POST", "PATCH", "DELETE"]
, corsRequestHeaders = ["Authorization", "Content-Type", "Cookie", "X-XSRF-TOKEN", "Origin", "X-Requested-With", "Accept",
"Accept-Language", "Content-Language"]
, corsExposedHeaders = Just ["Set-Cookie", "X-XSRF-TOKEN"]
, corsMaxAge = Nothing
, corsVaryOrigin = True
, corsRequireOrigin = False
, corsIgnoreFailures = False
}
在对“https://api.website.com”执行 GET 请求后,前端成功接收到为域“api.website.com”设置的 XSRF-TOKEN cookie(secure = false,httpOnly = false,sameSite = Lax)(我也试过 SameSite = 无,安全 = 真)。现在,当向“https://api.website.com”发出 POST 请求时,我无法让 axios(或手动)将令牌从 cookie 添加到 X-XSRF-TOKEN 标头。以下是我尝试提出请求的方式:
declare module 'axios' {
export interface AxiosRequestConfig {
crossDomain?: boolean;
}
}
const xsrfCookieName = 'XSRF-TOKEN'
const xsrfHeaderName = 'X-XSRF-TOKEN'
export const api = axios.create({
baseURL: endpoint,
timeout: 5000,
xsrfCookieName,
xsrfHeaderName,
withCredentials: true,
crossDomain: true
})
//...
export const postWarehouses = (warehouse: string) =>
api
.post('/admin/warehouses', warehouse, { withCredentials: true })
我还尝试从 cookie 中手动添加标头:
function attachCsrfToken(request: AxiosRequestConfig) {
const csrfToken =
['POST', 'PUT', 'PATCH'].includes(request.method ?? 'GET') &&
document.cookie &&
document.cookie.length
? document.cookie.match(new RegExp(`${xsrfCookieName}=([^;]+)`))
: {} as RegExpMatchArray
if (csrfToken && csrfToken.length > 1) {
request.headers[xsrfHeaderName] = csrfToken[1] ?? ''
}
return request
}
api.interceptors.request.use(attachCsrfToken)
显然,前端只能读取域“https://admin.website.com”上的 cookie。所以我该怎么做?
我的后端设置了必要的标题:
access-control-allow-credentials: true
access-control-allow-origin: https://admin.website.com
access-control-expose-headers: Set-Cookie, X-XSRF-TOKEN
顺便说一句,我还控制 XSRF-TOKEN cookie 的创建。我宁愿避免“代理”解决方案 - 合并我的域。
解决方案
您是否尝试过测试问题是否仍然存在于移动设备上?我遇到了同样的问题,基本上是开发和生产 csrf 令牌冲突,问题只针对我,而不是用户,我通过删除 127.0.0.1、web.site 和 api.web 的所有 cookie 解决了这个问题。地点
推荐阅读
- django - Django Rest Framework:使用令牌登录获取用户详细信息和权限
- angular - Angular Universal + Webpack 4:ReferenceError:未定义窗口
- laravel - Laravel 更新 SESSION_DOMAIN 后返回错误 419
- http - nginx - 根据 wget 请求运行 shell/python 脚本
- javascript - D3.js - 获取弧内的随机点
- c++ - 有效地将数组的一部分设置为零
- spring - 如何在 Spring Boot 应用程序中使用 AOP 捕获 Http 动词和 api 端点
- c# - 当我在编辑器的 Assets 中过滤以按类型搜索 Prefab 时,它会找到 45 个预制件,但在我的脚本中它找到 54 个正确的预制件是什么?
- jenkins - 詹金斯输入步骤输入对话框不显示
- powershell - 使用 PowerShell 打开大型 csv 文件并导出特定列