【发布时间】: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,所以请不要推荐。)
【问题讨论】: