【问题标题】:CSRF Token Name on Django Documentation is not Matching the Actual Name of the Variable in AJAX HeaderDjango 文档上的 CSRF 令牌名称与 AJAX 标头中变量的实际名称不匹配
【发布时间】:2019-01-11 20:14:51
【问题描述】:

我一直在努力发送和接收 CSRF 令牌,最后我发现 Django 无法获取令牌值,因为它的名称与文档中推荐的名称不同。为什么?

(我在 HTTPS 地址上执行 AJAX,请求是跨站点的。) Django documentation 建议我通过以下方式将令牌添加到 AJAX 标头:

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

在这里,名称是 X-CSRFToken,不知何故变成了 HTTP_X_CSRFTOKEN。 另一方面,Django 在 CSRF_COOKIE 下查找 cookie。

CsrfViewMiddleware 的 csrf.py 中的第 278 行:

csrf_token = request.META.get('CSRF_COOKIE')
if csrf_token is None:
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
   return self._reject(request, REASON_NO_CSRF_COOKIE)

我无法更改变量名,因为我收到此错误:

Request header field CSRF_COOKIE is not allowed by Access-Control-Allow-Headers in preflight response.

所以,我最终将源代码中的变量名从 CSRF_COOKIE 更改为 HTTP_X_CSRFTOKEN。有什么办法可以使这项工作?

(我不做@csrf_exempt,所以请不要推荐。)

【问题讨论】:

    标签: ajax django csrf


    【解决方案1】:

    问题不在于 Django,如果您仔细阅读此处:https://docs.djangoproject.com/en/2.0/ref/csrf/#how-it-works,您将了解它是如何工作的以及它们遵循什么样的逻辑。

    问题是你不允许标题:

    Request header field CSRF_COOKIE is not allowed by Access-Control-Allow-Headers in preflight response.
    

    如果您搜索此 ACAH,您会发现您必须编辑服务器配置文件以允许此类帖子。

    另一种情况是您可能没有正确发送标头,这就是它寻找 cookie 的原因。在这种情况下,您可以尝试将其添加到您的标题中:

    xhr.setRequestHeader('X-CSRFToken': $('meta[name="token"]').attr('content') });
    

    【讨论】:

    • 嗨,谢谢。你有链接到解释 ACAH 的页面吗?找不到。如果这很重要,我不会使用 REST 框架。
    猜你喜欢
    • 1970-01-01
    • 2016-05-17
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多