Reputation: 2235
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
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