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 错误消息

用于 Ajax 的 Django csrf 令牌

Django - % csrf_token % 在模板中使用,但上下文没有提供值

30_Django中关于使用ajax发送请求中`csrf_token`的问题和解决