django: csrf_token for multiple forms and ajax req

2019-08-12 01:30发布

My website has a single page with 2 forms and 3 ajax-based POST calls. I have used csrf_token in one of the forms. Also, to be able to perform csrf-safe ajax calls, I am using the guidelines posted on the official documentation: https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ and this blog: https://realpython.com/blog/python/django-and-ajax-form-submissions/

As suggested, by using this peice of code https://gist.github.com/broinjc/db6e0ac214c355c887e5 in my javascript file, it seems I am able to perform POST requests without any problems.

Questions:

  1. 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?
  2. 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.
  3. Should I be doing anything extra for my ajax calls or are they fine?
  4. Is there a way to check in views.py function that the call is csrf safe?

Let me know if you need more information and I will be happy to elaborate further.

1条回答
仙女界的扛把子
2楼-- · 2019-08-12 02:34

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?

I hope not ;) Enabling the CsrfViewMiddleware in Django is sufficient to ensure that your views are protected against cross-site request forgery. If you use two separate HTML forms (two <form></form> tags), both forms need to have a hidden CSRF token field. If you use two Django forms in a single form tag, you only need it once.

If that javascript snippet would send the token with any request, not just AJAX requests, you would only need the token once, but I don't believe it does, so you need it in each HTML form.

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.

The {% csrf_token %} tag creates a hidden field for you, so essentially you are using a hidden field.

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

The javascript you included sets a header to the value of the CSRF token on every AJAX request. This header replaces the post data that is usually sent by the hidden field in a form. Any AJAX calls you send through jQuery will have this header, you won't need to do anything else.

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

Not really. As long as you have the CsrfViewMiddleware enabled and you're not using the csrf_exempt decorator, your view is protected. If the call is unsafe, the middleware will return a 403 Forbidden response before the request even reaches the view.

查看更多
登录 后发表回答