Я новичок в веб-разработке и в настоящее время столкнулся с проблемой, которую не могу легко решить. Я использую Django3.2.6, django restframework (DRF) 3.14, vue3.0 и axios (для вызовов API). Я написал APIView для блокировки модели при редактировании ее экземпляра:
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)
Для внешнего интерфейса я создал приложение Vue, которое периодически вызывает мой LockCmAPI, чтобы заблокировать экземпляр и предотвратить его редактирование другими:
let vue = Vue.createApp({
delimiters: ['[[', ']]'],
data: function(){
return{
current_cm: cm_obj,
intervall: null,
}
},
methods: {
lockCmHeartbeat(){
console.info('locking');
console.info(`${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.info('lock');
console.info(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');
После запуска моего кода я получаю ответ 403 с сообщением "Request failed with status code 403"
. Когда я углубился в ответ, я получил это "{\"detail\":\"CSRF Failed: CSRF token missing or incorrect.\"}"
в моем ответном тексте.
Мой вопрос:
СПАСИБО :D
Для всех, у кого будет такая же проблема. Поскольку предоставленный мной csrftoken точно такой же, как csrftoken, который я видел в своем файле cookie с именем csrftoken. Это должна была быть другая проблема... После прочтения документации по django https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_HEADER_NAME:
По умолчанию: 'HTTP_X_CSRFTOKEN' Имя заголовка запроса, используемого для CSRF-аутентификация.
Как и в случае с другими заголовками HTTP в request.META, полученное имя заголовка с сервера нормализуется путем преобразования всех символов в в верхнем регистре, заменив все дефисы символами подчеркивания и добавив Префикс HTTP_ к имени. Например, если ваш клиент отправляет Заголовок «X-XSRF-TOKEN», параметр должен быть «HTTP_X_XSRF_TOKEN».
Я понял, что имя моего заголовка csrf отличается от CSRF_HEADERNAME по умолчанию в djangos. Чтобы решить эту проблему, я настроил xsrfHeadername в своем запросе axios, который выглядит следующим образом:
axios.post(`${BACKEND_PATH + LOCK_PATH + this.current_cm.id}/`, this.current_cm, {
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFTOKEN',
})