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))
}
...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With