Ive found that, using Django, CSRF tokens are required under scenarios (and should in general be):
For all incoming requests that are not using HTTP GET, HEAD, OPTIONS or TRACE, a CSRF cookie must be present, and the ‘csrfmiddlewaretoken’ field must be present and correct. If it isn’t, the user will get a 403 error.
I have found a great deal of documentation and examples relevant only when Django is rendering the page templates. In this case, your templates can use special {% csrf_token %}
token to add a hidden field that, when submitted, allows the backend to effectively validate the form's origin.
So how does this generally work when Django is not rendering the pages? I can contrive a simple example where the frontend just uses React and the backend is strictly an API.
I've found other documentation that claim you can decorate your backend API methods with such things as @csrf_protect
or @ensure_csrf_cookie
. However, the decorators instruct Django to set CSRF tokens on backed replies for some view/API request.
Imagine a simple "login" type of scenario:
- React frontend renders Login page with form
- React frontend submits form with PUT to backend for auth
According to any docs or examples I can find, it would seem the React frontend would need to make some kind of preflight request to get the CSRF token. While no document says this explicitly, it seems necessary.
- React frontend renders Login page with form
- React frontend makes request to API endpoint for login (just to get CSRF token)
- Django backend replies to (2) with CSRF token set
- React frontend submits form (CSRF token set) with PUT to backend for auth
This question has a great answer but it seems to assume the CSRF token is already present in the document somehow. Where does it come from? In the simple login scenario I describe above there are no backend requests (that would have replied and added the csrftoken cookie) prior to the PUT form submission for auth.
Does this assume users are already authenticated and logged in?