django:csrf_token 多个表单和单个页面上的 ajax 请求

django: csrf_token for multiple forms and ajax requests on a single page

我的网站只有一个页面,其中包含 2 个表单和 3 个基于 ajax 的 POST 调用。我在其中一种形式中使用了 csrf_token 。此外,为了能够执行 csrf-safe ajax 调用,我使用了官方文档中 posted 的指南:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ and this blog: https://realpython.com/blog/python/django-and-ajax-form-submissions/

按照建议,通过在我的 javascript 文件中使用这段代码 https://gist.github.com/broinjc/db6e0ac214c355c887e5,我似乎能够毫无问题地执行 POST 请求。

问题:

  1. 在其中一种形式中使用 csrf_token 以及 javascript 代码(如上所述)是否足以确保 csrf 伪造?我应该在第二种形式中使用 csrf_token 吗?
  2. 正如 SO post Generating CSRF tokens for multiple forms on a single page 中所建议的那样,似乎使用相同的标记应该没问题。但是,需要说明的是,我在第一个表单中使用的是 {% csrf_token %},而不是 post 中提到的隐藏字段。我在第二种形式中没有使用任何 csrf_token
  3. 我应该为我的 ajax 电话做任何额外的事情吗?
  4. 有没有办法检查 views.py 函数调用是否 csrf 安全?

如果您需要更多信息,请告诉我,我很乐意进一步详细说明。

Is using csrf_token in one of the forms along with the javascript code (mentioned above) sufficient to ensure csrf forgery? Should I be using csrf_token in the second form?

我希望不会 ;) 在 Django 中启用 CsrfViewMiddleware 足以确保您的观点受到保护 against cross-site 请求伪造。如果您使用两个单独的 HTML 表单(两个 <form></form> 标签),两个表单都需要有一个隐藏的 CSRF 令牌字段。如果您在单个 form 标记中使用两个 Django 表单,则只需要一次。

如果 javascript 代码段会随任何请求发送令牌,而不仅仅是 AJAX 请求,那么您只需要令牌一次,但我不相信它需要,所以您需要它以每个 HTML 形式出现。

As suggested in this SO post Generating CSRF tokens for multiple forms on a single page it seems using same token should be fine. However, just to be clear, I am using {% csrf_token %} in my first form and not a hidden field as mentioned in the post. And I am not using any csrf_token in my second form.

{% csrf_token %} 标签为您创建了一个隐藏字段,因此本质上您 使用隐藏字段。

Should I be doing anything extra for my ajax calls or are they fine?

您包含的 javascript 在每个 AJAX 请求中将 header 设置为 CSRF 令牌的值。此 header 替换了通常由表单中的隐藏字段发送的 post 数据。您通过 jQuery 发送的任何 AJAX 呼叫都会收到此 header,您无需执行任何其他操作。

Is there a way to check in views.py function that the call is csrf safe?

不是真的。只要您启用了 CsrfViewMiddleware 并且您没有使用 csrf_exempt 装饰器,您的视图就会受到保护。如果调用不安全,中间件会在请求到达视图之前 return 一个 403 Forbidden 响应。