使用 React 和 Django 构建简单的用户身份验证,但到目前为止只进行了注册编码。我已经尝试让它工作几个小时,但我感到非常沮丧。反应端已构建,注册页面正在从 django 端口 8000 运行。
开发服务器正在获取 cookie 并将其完美设置在本地主机端口 8000 上。我将其放在注册表单中的隐藏输入字段中,然后在 auth.js 中使用 js-cookie 完美检索 cookie(我可以使用控制台.日志)。然后我使用 axios 发送它,并在标头中使用 withCredentials=true 的 cookie。我收到以下错误:
错误
Forbidden (CSRF cookie not set.): /accounts/register
[28/Feb/2024 19:39:57] "POST /accounts/register HTTP/1.1" 403 2869
我尝试过各种其他发送 cookie 的方法。我已设置所有相关的 CORS 设置。
views.py
@method_decorator(ensure_csrf_cookie, name='dispatch')
class GetCSRFToken(APIView):
permission_classes = (permissions.AllowAny, )
def get(self, request, format=None):
return Response({ 'success': 'CSRF cookie set'})
auth.js
import axios from 'axios';
import {
REGISTER_SUCCESS,
REGISTER_FAIL
} from './types';
import Cookies from 'js-cookie'
export const register = (username, password, re_password) => async dispatch => {
const config = {
withCredentials: true,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get('csrftoken')
}
};
const body = JSON.stringify({ username, password, re_password });
try {
const res = await axios.post(`${process.env.REACT_APP_API_URL}/accounts/register`, body, config);
if (res.data.error) {
dispatch({
type: REGISTER_FAIL
});
} else {
dispatch({
type: REGISTER_SUCCESS
})
}
} catch (err) {
dispatch({
type: REGISTER_FAIL
});
}
}
CSRFToken.js(从这里获取csrf令牌。这有效)
import React, { useState, useEffect} from 'react'
import axios from 'axios'
const CSRFToken = () => {
const [csrftoken, setcsrftoken] = useState('');
const getCookie = (name) => {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
let cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(`${process.env.REACT_APP_API_URL}/accounts/csrf_cookie`)
setcsrftoken(getCookie('csrftoken'));
} catch (err) {
console.log("error");
}
}
fetchData();
}, []);
return (
<input type="hidden" name="csrfmiddlewaretoken" value={csrftoken} />
);
}
export default CSRFToken
Axios 配置具有跨站点请求伪造(XSRF)保护的默认值,您可以设置 xsrfHeaderName 和 xsrfCookieName 属性。这些属性指定用于传输跨站点请求伪造令牌的 HTTP 标头和 cookie 的名称。
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";