简体   繁体   中英

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()
        
    
    class CustomAuthentication(JWTAuthentication):
        
        def authenticate(self, request):
            .....
            validated_token = self.get_validated_token(raw_token)
            
            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))
    }
    ...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM