CSRF验证在跨域POST请求的生产中失败

时间:2019-04-25 05:05:39

标签: django cross-domain csrf

HTTP_X_CSRFTOKEN标头与csrftoken cookie内的内容不匹配。

如何检查Cookie?跨域请求的“响应”标头中未显示Set-Cookie。

我已经按照以下说明进行操作:

CSRF with Django, React+Redux using Axios

有趣的是,我在服务器请求标头上发现“ X-CSRFTOKEN”转换为“ HTTP_X_CSRFTOKEN”。

可以在localhost下的开发环境中正常工作(尽管我使用2个不同的端口-一个用于django,另一个用于我的前端)。

更新:

似乎没有为跨域rquest正确设置csrktoken cookie(尽管浏览器在“请求标头”中显示了它),因此X-CSRFTOKEN不会被发送。

我最终添加了一个API调用,以使用GET请求返回当前的csrftoken,然后使用X-CSRFTOKEN标头将其发送回去。

2 个答案:

答案 0 :(得分:0)

您将必须通过CORS Access-Control-Expose-Headers指令使X-CSRFTOKEN标头可访问。示例:

Access-Control-Expose-Headers: X-CSRFTOKEN

此标头必须由您的API或Web服务器设置,以便浏览器可以在CORS预检请求期间看到它。

答案 1 :(得分:0)

首先您没有提到如何从服务器获取csrftoken,所以我假设它已经存在于您的浏览器中。 除X-CSRFToken标头外,还使用withCredentials: true在请求中包含cookie。 我正在使用js-cookie库从Cookie中获取csrftoken

import Cookies from 'js-cookie';

axios({
    url: 'http://localhost:8000/graphql',
    method: 'post',
    withCredentials: true,
    data: {
        query: `
            {
                // Your query here
            }     
        `
    },
    headers: {
        "X-CSRFToken": Cookies.get('csrftoken')
    }
})

还假设您使用的是CORS_ALLOW_CREDENTIALS = True,则将settings.py添加到您的django-cors-headers中。否则,cookie将不被接受。