我一直在努力发送和接收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,所以不建议这样做。)
答案 0 :(得分:0)
问题不在于Django,如果您在此处仔细阅读:https://docs.djangoproject.com/en/2.0/ref/csrf/#how-it-works,您将了解它的工作原理以及遵循的逻辑。
问题是您不允许标题:
[dir] /deep/ .total-deposit_value {
margin-top: 5px;
}
如果搜索此ACAH,您将发现必须编辑服务器配置文件以允许此类发布。
另一种情况是您可能没有正确发送标头,这就是为什么它在寻找cookie。在这种情况下,您可以尝试将其添加到标题中:
Request header field CSRF_COOKIE is not allowed by Access-Control-Allow-Headers in preflight response.