如何使用 Axios 将 CSRF Cookie 从 React 发送到 Django Rest Framework
How to send CSRF Cookie from React to Django Rest Framework with Axios
我想使用 Axios[=26] 从 React 应用发出 POST 请求=] 到 Django Rest Framework 后端。我已经设法从后端获得了一个 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"
Django 默认使用 X-CSRFTOKEN
作为 csrf header,参见 here. The option CSRF_COOKIE_NAME
you use in your Django settings only changes the cookie name, which by default is csrftoken
, see here.
要解决您的问题,请在您的 axios 调用中使用此 header: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',
]
此外,如果您创建一个 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
我想使用 Axios[=26] 从 React 应用发出 POST 请求=] 到 Django Rest Framework 后端。我已经设法从后端获得了一个 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"
Django 默认使用 X-CSRFTOKEN
作为 csrf header,参见 here. The option CSRF_COOKIE_NAME
you use in your Django settings only changes the cookie name, which by default is csrftoken
, see here.
要解决您的问题,请在您的 axios 调用中使用此 header: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',
]
此外,如果您创建一个 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