Pradip Kachhadiya
Pradip Kachhadiya

Reputation: 2235

When I set CSRF_COOKIE_HTTPONLY = True then 403 (Forbidden) error occurred

In my settings.py:

...
CSRF_COOKIE_HTTPONLY = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_SECURE = False
CORS_ALLOW_CREDENTIALS = True

authenticate.py:

    from rest_framework_simplejwt.authentication import JWTAuthentication
    from django.conf import settings
    from rest_framework import exceptions
    from rest_framework.authentication import CSRFCheck

    def enforce_csrf(request):
        """
        Enforce CSRF validation.
        """
        check = CSRFCheck()
        # populates request.META['CSRF_COOKIE'], which is used in process_view()
        check.process_request(request)
        reason = check.process_view(request, None, (), {})
        print(reason)
        if reason:
            # CSRF failed, bail with explicit error message
            raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
    
    class CustomAuthentication(JWTAuthentication):
        
        def authenticate(self, request):
            .....
            validated_token = self.get_validated_token(raw_token)
            enforce_csrf(request)
            return self.get_user(validated_token),validated_token

Error:

CSRF token missing or incorrect.

Forbidden: /photos/photo_support/

when I set CSRF_COOKIE_HTTPONLY = False then all work very well. What's the reason when I set CSRF_COOKIE_HTTPONLY = True then they me throw 403 Forbidden error.

My Frontend is ReactJS.

TestMe.js:

Axios.defaults.withCredentials = true
Axios.defaults.xsrfCookieName = 'csrftoken';
Axios.defaults.xsrfHeaderName = 'X-CSRFToken';

const TestMe = () => {
    ....
    const payHandle = () => {
        Axios.post('http://localhost:8000/photos/photo_support/', {
            data:data
        })
        .then(res => {
             console.log(res.data)
        })
        .catch(error => alert(error.message))
    }
    ...

Upvotes: 3

Views: 1344

Answers (1)

Karthic Raghupathi
Karthic Raghupathi

Reputation: 2061

I take it you are reading the CSRF token from the cookie at this point. As mentioned in the docs, setting CSRF_COOKIE_HTTPONLY=True doesn't provide you any practical benefit so if everything works with it being set to False, you should probably continue to do so.

However if you still need to set it to True, then you will need to read the value of the CSRF token from the hidden form field as mentioned in the docs again. These snippets are from the documentation:

Read the value like so:

{% csrf_token %}
<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
</script>

Send it in your AJAX request like so:

const request = new Request(
    /* URL */,
    {
        method: 'POST',
        headers: {'X-CSRFToken': csrftoken},
        mode: 'same-origin' // Do not send CSRF token to another domain.
    }
);
fetch(request).then(function(response) {
    // ...
});

I'm not well versed in React or Axios so you may have to adapt this concept to your needs.

Upvotes: 1

Related Questions