Django 1.3 中的 Ajax CSRF 问题
根据 django 文档,对于 1.3 中的 ajax post 请求(至少使用 Jquery),我们只需要添加此 片段 到主 js 文件。此代码片段从 cookie 中获取 csrftoken,然后为所有 ajax 请求设置它。这是可行的,但是如果 cookie 中不存在 csrftoken 怎么办?我认为 render_to_response 和 render 都会自动检查会话中是否存在 csrftoken,并在 token 不存在时为我们设置它。但他们不是。那么,我需要自己实现吗?或者也许还有另一种方法来处理ajax csrf保护?
According to django documentation, for ajax post request in 1.3 (at least with Jquery), we just need to add this snippet to main js file. This snippet get csrftoken from cookies, and then set up it for all ajax request. That's work, but what if csrftoken don't exist in cookies? I thought render_to_response and render both automatically checks if csrftoken in sessions, and set it for us, if token not there. But they are not. So, i need to implement it by myself? Or maybe there is another way to handle ajax csrf protection?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当页面上没有已使用 {% csrf_token %} 的表单时,将不会发送 cookie。因此,正如您所指出的,当您尝试在此类页面上使用 Ajax 时,您将收到错误。如果您的网站混合了包含各种表单和 ajax 帖子组合的页面,这将导致不稳定的行为。
此问题已被报告并修复:https://code.djangoproject.com/ticket/15354
补丁中的解决方案将随 1.3.1 一起推出,即 Ensure_cookie_csrf 装饰器。该装饰器在 1.3 或 1.2.5 中不存在
,但是无需等待。只需将此行添加到包含 AJAX 发布 CSRF 表单的任何视图中:
示例:
仅供参考 - 这正是该装饰器的作用。
When there is no form on a page that is already using {% csrf_token %}, the cookie will not be sent. Therefore, as you noted, you will get an error when you attempt to use Ajax on such a page. This will lead to erratic behavior if you have a site with a mix of pages with various combinations of forms and ajax posts.
This has already been reported and fixed: https://code.djangoproject.com/ticket/15354
The solution in the patch, will should roll out with 1.3.1, is the ensure_cookie_csrf decorator. That decorator does not exist in 1.3 or 1.2.5
No need to wait, however. Just add this line to any view which contains AJAX posts a CSRF form:
Example:
FYI - this is exactly what that decorator does.
如果在模板中使用模板标记
{% csrf_token %}
来生成请求,或者如果您调用get_token
(使用来自 django.middleware.csrf 的request
对象作为参数)。get_token
函数在request
对象上设置元信息,该对象又告诉django.middleware.csrf.CsrfViewMiddleware
中间件设置 cookie。Your cookie will only contain the CSRF token, if either the template tag
{% csrf_token %}
was used in the template to generate the request, or if you callget_token
(with therequest
object as argument) fromdjango.middleware.csrf
.The
get_token
function sets metainformation on therequest
object that in turn tells thedjango.middleware.csrf.CsrfViewMiddleware
middleware to set the cookie.对于 Ajax,您应该在每个请求中传递 csrf 令牌。对于 jQuery,我使用以下代码:
As for Ajax, you should pass the csrf token with every request. For jQuery, I use the following code:
我发现解决这个问题的一种方法是使用预先存在的表单作为 AJAX 数据的起点。
然后,您可以通过 JQuery 的 Serialize 函数在 JavaScript 中使用它:
您甚至可以在该隐藏表单中使用隐藏字段,这样您就不必使用字符串连接来构建 POST 数据。
One way that I've found to get around this is by using a preexisting form as a starter point for your AJAX data.
Then you can use this in your JavaScript via JQuery's Serialize function:
You can even use hidden fields within that hidden form so that you don't have to use string concatenation to built your POST data.
如果您使用 @csrf_protect 装饰器,请确保带有表单的视图和正在发布数据的视图都使用该装饰器。
我有类似的问题。我只在帖子视图上有@csrf_protect,它在本地测试工作正常,但是当我上线时,出现了 403 验证失败的问题,将装饰器添加到页面视图修复了此问题
If you are using the @csrf_protect decorator, make sure that both the view with the form and the view that the data is being posted to use the decorator.
I had a similar issue. I only had @csrf_protect on the post view which worked fine testing locally but when i went live o got a 403 verification failed issue adding the decorator tot he page view fixed this