I think the problem is in part due to the fact im not using the HTML template tag since, I’m creating a project using the JS generating the HTML from there. For addressing this in the HTML i added this script(before the js script I use):
<script> var csrfToken = '{{ csrf_token }}'; </script>
Im using the following script after the form code to send the information to my django project:
const apiSendDataUser = (event) => {
event.preventDefault();
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const formData = new FormData (event.target);
fetch('https://127.0.0.1:8000/myProject/post_user',{
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': csrfToken
}
})
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error('Error: ' + response.status);
}
})
.then(data => {
// Handle the response data
console.log(data);
})
.catch(error => {
// Handle any errors
console.error(error);
});
};
And finally, the post_user function on the views.py is:
@require_POST
def post_user(request):
try:
email = request.POST['email']
if not User.objects.filter(email).exists() :
username = request.POST['username']
password = request.POST['password']
User.objects.create_user(username=username, password=password, email=email)
return JsonResponse(
{
"success":True,
"message": "Usuario añadido."
}
)
except Exception as e:
return JsonResponse({
"success": False,
"message": e.args[0]
}, status=404)
I think is all, I dont know how to handle things with the CSRF token, I hope you might help me in this regard. Thanks.
On this problem, I’ve tried to go to django documentation but still dont understand why im having this problems.
2
Answers
The CSRF token is included in the HTML of the Django-rendered webpage as a cookie. You’re trying to include it in your script using a Django template tag, but since the form is generated using JavaScript, this token is not included correctly.
Here’s how you can retrieve the CSRF token from the cookie:
After you can use it in the
fetch
request.Also, check if Django settings have
CSRF_COOKIE_NAME
equal tocsrftoken
.If it has another value, you need to replace it when calling the
get_cookie
function.If this still doesn’t work, make sure that your Django view is properly set up to handle CSRF. The Django
@csrf_exempt
decorator can be used to test it.Answer
In order to use
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
you have to have
{% csrf_token %}
somewhere in your HTML template.Why this works
When Django sees this it will replace
{% csrf_token %}
with something like<input type="hidden" name="csrfmiddlewaretoken" value=".............................">
,which your JavaScript can then get using the
QuerySelector
. Usually it is placed within the<form>
:But since you are using JavaScript to send the form, it can be placed anywhere in your HTML:
Why your code does not work
When Django sees this:
<script> var csrfToken = '{{ csrf_token }}'; </script>
it will replace{{ csrf_token }}
with a random value, the actual token, so it will look something like this:Note the difference. Here with
{{ csrf_token }}
your querySelector fails, since there is no hidden input generated with thename=csrfmiddlewaretoken
, which is what happens with{% csrf_token %}