Axios 请求未向 Django 服务器发送预期的 cookie 标头

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

我正在尝试使用 React 应用程序中的 Axios 发布请求将文件上传到 Django 服务器。服务器期望 CSRF cookie 包含在请求标头中。

请求已经包含了我能找到的所有设置 cookie 的方法。通过

document.cookie
,设置
withCredential: true
,指定
Cookie
表头。

这是我的 Axios 请求:

const onSubmit = async (data) => {
    const formData = new FormData()
    formData.append('file', data.file[0])

    const csrftoken = getCookie('csrftoken');
    document.cookie = `csrftoken=${csrftoken}`

    const res = await axiosInstance.post('/upload/', formData, {
        timeout: 0,
        headers: {
            'Cookie': `csrftoken=${csrftoken}`, 
            'Content-Type': 'multipart/form-data',
            'x-csrftoken': csrftoken,
        },
        withCredentials: true,
    })

    console.log(res)
}

这是我的 Django 视图:

def upload_file(request):
    form = UploadFileForm()
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)

        if form.is_valid():
            file_id = save_file_to_database(request.FILES['file'])
            response = JsonResponse({'id': file_id}, status=201)
            return response
        else:
            response = HttpResponse({'message': 'Upload failed'}, status=400)
            return response

    return render(request, 'upload.html', {'form': form})

此外,我相信我已经在

settings.py
中正确设置了相关的Django设置:

CORS_ORIGIN_WHITELIST = (
    "http://localhost:8000",
    "http://127.0.0.1:5173",
)

CSRF_TRUSTED_ORIGINS = [
    "http://127.0.0.1:5173"
]

SESSION_COOKIE_SAMESITE = 'None'

我该怎么做才能确保 CSRF cookie 包含在请求标头中或以其他方式满足 CSRF 要求?可以肯定的是,如果我们将

@csrf_exempt
添加到视图中,路由会起作用,所以它应该真的是一个 CSRF 问题。

reactjs django cookies axios csrf
1个回答
0
投票

您只需要在

formData
中包含令牌。无需标头或 cookie 操作:

const onSubmit = async (data) => {
    const formData = new FormData()
    formData.append('file', data.file[0])
    formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));

    const res = await axiosInstance.post('/upload/', formData, {
        timeout: 0,
        headers: {
            'Content-Type': 'multipart/form-data',
        },
        withCredentials: true,
    })

    console.log(res)
}

提示:当您不确定是否正在发送 cookie、标头等时,请检查浏览器开发工具中的网络选项卡。如果您在请求的“请求标头”部分看到它们,那么它们are 正在发送,这意味着问题出在服务器端。在这种情况下,对于

multipart/form-data
,Django 需要
csrfmiddlewaretoken
表单字段中的令牌。对于
application/json
请求,您可以使用
X-CSRFToken
标头。

© www.soinside.com 2019 - 2024. All rights reserved.