如何使用 Axios 将 CSRF Cookie 从 React 发送到 Django Rest Framework
Posted
技术标签:
【中文标题】如何使用 Axios 将 CSRF Cookie 从 React 发送到 Django Rest Framework【英文标题】:How to send CSRF Cookie from React to Django Rest Framework with Axios 【发布时间】:2019-06-03 11:36:20 【问题描述】:我想使用 Axios 从 React 应用向 Django Rest Framework 后端发出 POST 请求.我已经设法从后端获得 CSRF 令牌,但我无法将它与我的请求一起发送,所以我总是收到 Forbidden (CSRF cookie not set.)
错误:
这是我的 React 应用的代码:
handleClick()
const axios = require('axios');
var csrfCookie = Cookies.get('XSRF-TOKEN');
console.log(csrfCookie)
axios.post('http://127.0.0.1:8000/es/api-auth/login/',
next: '/',
username: 'admin@admin.com',
password: 'Cancun10!',
,
headers:
'x-xsrf-token': csrfCookie, // <------- Is this the right way to send the cookie?
,
withCredentials = true,
)
.then(function (response)
console.log(response);
)
.catch(function (error)
console.log(error);
)
这是我的settings.py
CSRF 配置:
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = (
'xsrfheadername',
'xsrfcookiename',
'content-type',
'XSRF-TOKEN',
)
CORS_ORIGIN_WHITELIST = serverconfig.CORS_ORIGIN_WHITELIST
CSRF_TRUSTED_ORIGINS = serverconfig.CSRF_TRUSTED_ORIGINS
CSRF_COOKIE_NAME = "XSRF-TOKEN"
【问题讨论】:
【参考方案1】:另外,如果你创建一个 Axios 实例会更容易
const instance = axios.create(
baseURL: API_URL,
withCredentials: true,
xsrfHeaderName: 'X-CSRFToken',
xsrfCookieName: 'csrftoken',
)
并确保xsrfCookieName
和CSRF_COOKIE_NAME
具有相同的名称。请注意,如果CSRF_COOKIE_HTTPONLY
设置为 True,客户端 javascript 将无法访问 CSRF cookie:
# settings.py
CSRF_COOKIE_NAME = "csrftoken"
CSRF_COOKIE_HTTPONLY = False
CORS_EXPOSE_HEADERS = ["Content-Type", "X-CSRFToken"]
CORS_ALLOW_CREDENTIALS = True
【讨论】:
【参考方案2】:Django 默认使用X-CSRFTOKEN
作为 csrf 标头,参见here。您在 Django 设置中使用的选项 CSRF_COOKIE_NAME
仅更改 cookie 名称,默认情况下为 csrftoken
,请参阅 here。
要解决您的问题,请在您的 axios 调用中使用此标头:headers: 'X-CSRFTOKEN': csrfCookie
。
使用以下内容:
axios.post('http://127.0.0.1:8000/es/api-auth/login/',
next: '/',
username: 'admin@admin.com',
password: 'Cancun10!',
,
headers:
'X-CSRFTOKEN': csrfCookie,
,
,
)
另外,在您的 Django 设置中从 CORS_ALLOW_HEADERS
中删除 XSRF-TOKEN
,然后将 X-CSRFTOKEN
添加到其中。如果您不想删除 XSRF-TOKEN
,可以使用以下文档安全地将 X-CSRFTOKEN
添加到 CORS_ALLOW_HEADERS
,文档 here
# settings.py
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = list(default_headers) + [
'X-CSRFTOKEN',
]
【讨论】:
我试了你的回答,后端没有报错(这是后端控制台结果:"OPTIONS /es/api-auth/login/ HTTP/1.1" 200 0
),但是前端控制台报错:Access to XMLHttpRequest at 'http://127.0.0.1:8000/es/api-auth/login/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field x-csrftoken is not allowed by Access-Control-Allow-Headers in preflight response
跨度>
@HugoLuisVillalobosCanto 尝试在 Django 设置中将X-CSRFTOKEN
添加到CORS_ALLOW_HEADERS
。
我做到了,又回到了原点(Forbidden (CSRF cookie not set.)
)
@HugoLuisVillalobosCanto 尝试将 withCredentials: True
添加到 axios 配置中(在标题之后)。
我犯了一个错误。现在它正在工作,但我收到另一个错误:Forbidden (CSRF token missing or incorrect.)
)以上是关于如何使用 Axios 将 CSRF Cookie 从 React 发送到 Django Rest Framework的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS 和 Django:如何以正确的方式使用 axios 发送 csrf 令牌?
Express + React:CSRF Cookie 在生产中未定义,在本地工作
Laravel 6 会话和 CSRF Cookie 未设置——每次页面加载的会话数据库中的新条目
带有 axios 和 vue 的 laravel 5.8 中的 CSRF