django:csrf_token 用于单个页面上的多个表单和 ajax 请求
Posted
技术标签:
【中文标题】django:csrf_token 用于单个页面上的多个表单和 ajax 请求【英文标题】:django: csrf_token for multiple forms and ajax requests on a single page 【发布时间】:2015-10-30 05:33:46 【问题描述】:我的网站有一个页面,其中包含 2 个表单和 3 个基于 ajax 的 POST 调用。我在其中一种形式中使用了csrf_token
。此外,为了能够执行 csrf-safe ajax 调用,我使用了官方文档中发布的指南:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ 和此博客:https://realpython.com/blog/python/django-and-ajax-form-submissions/
正如建议的那样,通过在我的 javascript 文件中使用这段代码 https://gist.github.com/broinjc/db6e0ac214c355c887e5,我似乎能够毫无问题地执行 POST 请求。
问题:
-
在其中一种形式中使用
csrf_token
以及javascript 代码(上面提到的)是否足以确保csrf 伪造?我应该在第二种形式中使用csrf_token
吗?
正如这篇 SO 帖子 Generating CSRF tokens for multiple forms on a single page 中所建议的那样,使用相同的令牌似乎应该没问题。但是,为了清楚起见,我在第一个表单中使用% csrf_token %
,而不是帖子中提到的隐藏字段。而且我没有在我的第二种形式中使用任何csrf_token
。
我应该为我的 ajax 调用做一些额外的事情吗?
有没有办法在views.py
函数中检查调用是csrf
安全的?
如果您需要更多信息,请告诉我,我很乐意进一步详细说明。
【问题讨论】:
【参考方案1】:是否以其中一种形式使用 csrf_token 以及 javascript 代码(上述)足以确保 csrf 伪造?我可以做 第二种形式使用csrf_token?
我希望不是 ;) 在 Django 中启用 CsrfViewMiddleware
足以确保您的视图受到保护防止跨站点请求伪造。如果您使用两个单独的 html 表单(两个 <form></form>
标签),则两个表单都需要有一个隐藏的 CSRF 令牌字段。如果你在一个 form
标签中使用两个 Django 表单,你只需要它一次。
如果该 javascript sn-p 将随任何请求发送令牌,而不仅仅是 AJAX 请求,那么您只需要一次令牌,但我不相信它会这样做,因此您在每个 HTML 表单中都需要它。
正如这篇 SO 帖子为多个生成 CSRF 令牌所建议的那样 单个页面上的表单似乎使用相同的令牌应该没问题。 但是,为了清楚起见,我第一次使用 % csrf_token % 表单而不是帖子中提到的隐藏字段。而我不是 在我的第二种形式中使用任何 csrf_token。
% csrf_token %
标签为您创建了一个隐藏字段,因此基本上您正在使用一个隐藏字段。
我应该为我的 ajax 调用做一些额外的事情吗?还是可以?
您包含的 javascript 在每个 AJAX 请求上为 CSRF 令牌的值设置了一个标头。此标头替换通常由表单中的隐藏字段发送的帖子数据。您通过 jQuery 发送的任何 AJAX 调用都将具有此标头,您无需执行任何其他操作。
有没有办法在 views.py 函数中检查调用是 csrf 安全的?
不是真的。只要您启用了CsrfViewMiddleware
并且您没有使用csrf_exempt
装饰器,您的视图就会受到保护。如果调用不安全,中间件将在请求到达视图之前返回403 Forbidden
响应。
【讨论】:
以上是关于django:csrf_token 用于单个页面上的多个表单和 ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章
django 页面进行ajax post提交时,页面要添加{% csrf_token %}
django 页面进行ajax post提交时,页面要添加{% csrf_token %}
我无法使用有效的用户名和密码登录 Django 管理页面,它返回 % csrf_token % 禁止的 404 错误消息