0
votes

First, I know there are many questions regarding CSRF tokens / Django, but I haven't found any that are useful for the scenario that I am in.

I am attempting to use Django's built in password reset endpoints with a React frontend. My goal is to use the backend functionality (generating tokens, email responses, etc) while displaying the relevant forms through React instead of using Django templates. The front end and back end are hosted on two unique servers.

In my front end code, I make a call to the password_reset endpoint when my React component mounts to fetch the CSRF token.

    componentDidMount() {
        let url = "http://(raw ip address)/accounts/password_reset/"

        fetch(url, {
            credentials: 'include',
        })
    }

The token is received in the Response headers as

Set-Cookie: csrftoken=b...e; expires=Sun, 10 Jan 2021 21:50:20 GMT; Max-Age=31449600; Path=/; SameSite=Lax

Here are where my issues begin - I am unable to inspect the token in my storage tab and the token value is not present in document.cookie. Ideally, I would like to use something like the getCookie method that is demonstrated in the Django docs

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

But that assumes that the token value is properly stored in document.cookie.

My relevant Django settings are all the default values, although I have rotated through the valid options for CSRF_COOKIE_SAMESITE and CSRF_USE_SESSIONS to no avail.

As another note, if I make a POST request once the component is mounted, the token is successfully set on the Request - but I need to add the token in the body for the default Django authentication views!

Any suggestions or insight would be greatly appreciated!

Ian

1

1 Answers

0
votes

According to Django docs, if your view doesn’t render an html template with csrf_token tag in it, which I guess is your case since you are not using Django’s built-in template for output, the cookie will not be set. One possible solution to this would be wrap your view call to ensure_csrf_token decorator in your urlpatterns.