django - 跨域 POST 请求的 CSRF 验证在生产中失败
问题描述
HTTP_X_CSRFTOKEN 标头与 csrftoken cookie 中的内容不匹配。
如何检查 cookie?Set-Cookie 不会显示在跨域请求的响应标头中。
我已经按照以下说明进行操作:
使用 Django 的 CSRF,使用 Axios 的 React+Redux
有趣的是,我发现“X-CSRFTOKEN”在服务器请求标头上转换为“HTTP_X_CSRFTOKEN”。
在 localhost 下的开发环境中工作正常(尽管我使用 2 个不同的端口 - 一个用于 django,另一个用于我的前端)。
更新:
似乎没有为跨域请求正确设置 csrktoken cookie(尽管浏览器将其显示在请求标头中),因此不会发送 X-CSRFTOKEN。
我最终添加了一个 API 调用以使用 GET 请求返回当前的 csrftoken,然后使用 X-CSRFTOKEN 标头将其发回。
解决方案
你一开始没有提到你是如何csrftoken
从服务器获取的,所以我假设它已经存在于你的浏览器中。除了X-CSRFToken
标头,还使用withCredentials: true
. 我正在使用js-cookie
库csrftoken
从 cookie 中获取。
import Cookies from 'js-cookie';
axios({
url: 'http://localhost:8000/graphql',
method: 'post',
withCredentials: true,
data: {
query: `
{
// Your query here
}
`
},
headers: {
"X-CSRFToken": Cookies.get('csrftoken')
}
})
假设CORS_ALLOW_CREDENTIALS = True
您settings.py
使用的是django-cors-headers
. 否则,cookie 将不被接受。
推荐阅读
- c - 为什么允许递归会使 C 在 8 位 CPU 上变慢/效率低下
- node.js - 尝试解析 http 请求的 json 时,位置 1 处的 JSON 中出现意外令牌 o 错误
- docker - 在容器中运行 openGL 的问题
- json - TensorFlow 保存模型的数据输入 JSON 格式
- python-3.x - 无法使用 asyncio/aiohttp 返回 404 响应
- firebird - 如何以显示来自两个连接表的记录的形式编辑记录(Firebird - Lazarus)
- typescript - 用于 Grommet 的 RangeInput 组件的 onChange 事件的正确类型定义是什么?
- html - Web 应用程序的每个部分都应该是一个 React 组件吗?
- python - 在 gtk3 中选择单元格时颜色属性恢复
- javascript - 从 for 循环更新数字