I'm new to web development and am currently stucked at a problem I can't solve easily. I'm using Django3.2.6, django restframework (DRF) 3.14, vue3.0 and axios (to make API calls). I wrote an APIView to lock a model while editing an it's instance:
class LockCmAPI(APIView):
def post(self, request, **kwargs):
obj = get_object_or_404(CM, id=self.kwargs['pk'])
obj.lock()
print('locking object')
return HttpResponse(status=status.HTTP_200_OK)
For the frontend I created a Vue app that calls periodically my LockCmAPI to lock the instance and prevent others from editing it:
let vue = Vue.createApp({
delimiters: ['[[', ']]'],
data: function(){
return{
current_cm: cm_obj,
intervall: null,
}
},
methods: {
lockCmHeartbeat(){
console.log('locking');
console.log(`${BACKEND_PATH+LOCK_PATH+this.current_cm.id}/`);
axios.post(`${BACKEND_PATH+LOCK_PATH+this.current_cm.id}/`, this.current_cm, {
xsrfCookieName: 'csrftoken',
})
.then((response) => {
console.log('lock');
console.log(response);
});
}
},
mounted() {
this.lockCmHeartbeat();
this.intervall = setInterval(function(){
this.lockCmHeartbeat();
}.bind(this), FIVE_SEC_IN_MILISEC);
},
beforeDestroy() {
clearInterval(this.interval);
}
});
vue.mount('#cm_vue_block');
After running my code I get a 403 response with the message "Request failed with status code 403"
. When I looked further into the response I got this "{\"detail\":\"CSRF Failed: CSRF token missing or incorrect.\"}"
in my responseText.
My Question:
THX :D
For everyone who is going to have the same problem. Since the csrftoken I provided is exactly the same as the csrftoken I saw in my cookie named csrftoken. It had to be another issue...After reading the django documentation https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_HEADER_NAME :
Default: 'HTTP_X_CSRFTOKEN' The name of the request header used for CSRF authentication.
As with other HTTP headers in request.META, the header name received from the server is normalized by converting all characters to uppercase, replacing any hyphens with underscores, and adding an 'HTTP_' prefix to the name. For example, if your client sends a 'X-XSRF-TOKEN' header, the setting should be 'HTTP_X_XSRF_TOKEN'.
I realized my csrf headername is named different to djangos default CSRF_HEADERNAME. In order to solve this problem I configured xsrfHeadername in my axios request, which looks like this:
axios.post(`${BACKEND_PATH + LOCK_PATH + this.current_cm.id}/`, this.current_cm, {
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFTOKEN',
})