禁止(未设置 CSRF cookie),cookie 从 React axios 发送到 django 后端

问题描述 投票:0回答:1

使用 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
javascript reactjs django cookies axios
1个回答
0
投票

Axios 配置具有跨站点请求伪造(XSRF)保护的默认值,您可以设置 xsrfHeaderName 和 xsrfCookieName 属性。这些属性指定用于传输跨站点请求伪造令牌的 HTTP 标头和 cookie 的名称。

axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
© www.soinside.com 2019 - 2024. All rights reserved.