我正在测试发出 POST ajax 请求,但由于没有 csrftoken,我得到了 403。我关注了文档,但是它仍然不起作用,我发现名为 csrftoken 的 cookie 是empty,这意味着$.cookie("csrftoken")
return null。
有人可以告诉我原因以及如何设置csrftoken
到 cookie 中吗?
我正在测试发出 POST ajax 请求,但由于没有 csrftoken,我得到了 403。我关注了文档,但是它仍然不起作用,我发现名为 csrftoken 的 cookie 是empty,这意味着$.cookie("csrftoken")
return null。
有人可以告诉我原因以及如何设置csrftoken
到 cookie 中吗?
我认为您应该提供如何在 HTML/JS 代码和中间件设置中获取 csrf 令牌的代码。
首先,您应该检查是否django.middleware.csrf.CsrfViewMiddleware
已打开。
我有一个类似的问题,当我在 python 代码request.META.get('CSRF_COOKIE')
中获取令牌时。
当您在模板中使用此标记时 - {% csrf_token %}
Django 注意到该标记已呈现并将 Cookie 设置为CsrfViewMiddleware.process_response
. 如果您以其他方式获取令牌值,Django 将错过此标志。因此它会为您生成一个令牌,但不会设置相应的 cookie。
我在代码中有 2 个解决方法。您应该将它添加到用于生成带有 JS 代码的模板的视图中。
1.可以强制Django设置CSRF Cookie:
# Force updating CSRF cookie
request.META["CSRF_COOKIE_USED"] = True
2.如果你调用,Django 会自动设置 CSRF_COOKIE_USEDget_token
from django.middleware.csrf import get_token
# don't use direct access to request.META.get('CSRF_COOKIE')
# in this case django will NOT send a CSRF cookie. Use get_token function
csrf_token = get_token(request)
每个解决方案都应该单独工作。我建议使用get_token
您可能想要使用ensure_csrf_cookie
视图装饰器(从 Django 1.4 开始可用)。csrftoken
即使您不使用{{ csrf_token }}
模板标签,这也会设置cookie。
我遇到了同样的问题($.cookie('csrftoken') 返回了'undefined')。
问题出在我的 Django 配置中,我评论了以下行并且它有效:
#CSRF_COOKIE_HTTPONLY = True # Prevent client-side JavaScript access to the CSRF cookie
扩展o_c 的答案:通过注释该CSRF_COOKIE_HTTPONLY
行,csrf_token 值不再是“未定义”(在 Firefox firebug 中),而是显示为“真实”值,例如“qGuPe2Q7...等”。
Ajax 请求不再因403 Forbidden
错误而被拒绝并被正确执行(前提是在 AJAX 标头中设置了 csrf_token)。
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
首先,如果您正在设计应用程序,最好在标头或 POST 请求中使用 csrf Token,而不是在 cookie 中,因为:
如果你想在 django 中强制使用 cookie,你总是可以:
request.META["CSRF_COOKIE_USED"] = True
如果您没有在任何地方使用 {% csrf_token %} 在您的项目中。根据 [documentation][1],您无需执行任何其他操作,只需编写一个简单的 javascript 代码即可。其实这不是真的。您必须"request.META['CSRF_COOKIE_USED'] = True"
在每个视图中放置线条(或编写适当的装饰器)。