Django Csrf Cookie Not Set

Django CSRF Cookie Not Set

This can also occur if CSRF_COOKIE_SECURE = True is set and you are accessing the site non-securely or if CSRF_COOKIE_HTTPONLY = True is set as stated here and here

Django and React: csrf cookie is not being set in request header

I suggest to you that try to work with your both servers using HTTPS. Some help:
Django

  • How can I test https connections with Django as easily as I can non-https connections using 'runserver'?
  • https://timonweb.com/django/https-django-development-server-ssl-certificate/

To ReactJS simply use the same certificates generated to use in Django to tun the server with next command:

HTTPS=true SSL_CRT_FILE=path/server.crt SSL_KEY_FILE=path/server.key npm start

This with the goal of change your settings:

CSRF_COOKIE_PATH = '/'
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_COOKIE_SECURE = True
CSRF_TRUSTED_ORIGINS = [ "https://127.0.0.1:3000", ...]

But is not totally necessary.

Now, your view GetCSRFToken is incorrect because return a message.
This an example that I have implemented. The key is the decorator ensure_csrf_cookie

Views.py:

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie

class CsrfTokenView(APIView):
"""Send to the login interface the token CSRF as a cookie."""

@method_decorator(ensure_csrf_cookie)
def get(self, request, *args, **kwargs) -> Response:
"""Return a empty response with the token CSRF.

Returns
-------
Response
The response with the token CSRF as a cookie.
"""
return Response(status=status.HTTP_204_NO_CONTENT)

In ReactJS just code a useEffect with empty dependencies to do the request just after mount the component.

useEffect(() => {
axios.get('/url/csrf-token/', {
headers: { 'Authorization': null },
withCredentials: true,
}
).catch( () => {
alert('Error message.');
});
}, []);

At this point, you will be able to watch the cookie in 'developer tools'.
Finally, in your LoginView add the csrf_protect decorator to your post method to make sure the endpoint needs the CSRF_TOKEN.

Views.py:

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect, ensure_csrf_cookie
...

class LoginView(views.APIView):
...
@method_decorator(csrf_protect)
def post(self,request):
# code

Don't forget map the url of the csrf view and put the correct in the request (useEffect).

Also in your request of login, add withCredentials: true. This way the request sent the cookies (CSRF). Django is going to compare the header X-CSRFToken with the value of the cookie received and if match, it is going to execute the method body.

I think that's it.
Let me know if it works.



Related Topics



Leave a reply



Submit