Here tokens are stored in cookies. Cookies are unique per their Scope (Domain and Path) and cookie name.
In this case all cookies have same name - csrftoken
, they also have same domain - 127.0.0.1
, but path is unique for each cookie. So, different scope (more specifically, path) allows to have multiple cookies.
The most referenced and respected document describing protection measures from CSRF attack is OWASP Cross-Site Request Forgery Prevention Cheat Sheet (GitHub Markdown variant).
Generating one csrf token per user session and storing it in a cookie is most popular approach. Being associated with session makes it somewhat protected from cookie-altering. Note, that you should use additional methods (i.e. double submit cookie and also include token in request body) for protection, because cookies are sent automatically on request.
Session altering views (login / logout / password change) and other important and high-security views (i.e. money transfer) may and should be protected with advanced and / or additional techniques (i.e. user interaction).
Why multiple csrf tokens were returned?
Possible explanation of back-end behavior: it may be an attempt to add graphql support to the app. It also looks like a combination of graphql with rest.
A request was made to /graphql
endpoint, which in turn traverses all other rest api endpoints as if future POST / PUT / PATCH
request may be made to them, each of the endpoints / view add its own per-path / per-form
(or even per-request) csrftoken cookie to the response. Also, it looks like with this approach, next request is expected to be not to the /graphql
endpoint, but to one of the rest api endpoints / views url directly.
With Graphql you will have only one /graphql
endpoint and all requests will be made to it.
Also, having multiple csrf tokens (per endpoint) does not give much if any advantage.
For a way to add Graphql API
to django - check Graphene
And if you are looking at using separate front-end app with Django back-end you should definitely take a look at django-cors-headers (and use it).