Я переношу свой проект в Django Rest Framework, чтобы создать правильный REST API для моего проекта, я думаю, что это очень помогает в разработке API и делает его надежным, но я столкнулся с проблемой:
У меня есть модель входа и связанные представления ListCreateAPIView
и RetrieveUpdateDestroyAPIView
. Я могу успешно опубликовать новый экземпляр записи в списке через запрос ajax и предоставить csrfmiddlewaretoken
, как я бы сделал в обычном представлении Django.
POST entries/
Теперь я пытаюсь применить патч к существующему экземпляру, используя тот же csrfmiddlewaretoken
, например:
PATCH entries/3
Тогда код состояния ответа будет 403 FORBIDDEN
с ошибкой CSRF Failed: CSRF token missing or incorrect
, хотя я проверил в firebux, что csrfmiddlewaretoken
находится в данных запроса.
Я не знаю, что не так, и я не могу понять, где в коде отклонен запрос.
Примечание. Я могу исправить объект с помощью доступного для просмотра API Django Rest Framework.
Я надеюсь, что кто-то может помочь. Спасибо. Оливье
ИЗМЕНИТЬ
Я копался в коде, чтобы увидеть, где происходит отклонение запроса PATCH, и я нашел в django.middleware.csrt.py
следующее:
if csrf_token is None: #<--- csrf_token is defined
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
return self._reject(request, REASON_NO_CSRF_COOKIE)
# Check non-cookie token for match.
request_csrf_token = ""
if request.method == "POST": #<--- This fails but request_csrf_token is in request.DATA
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
if request_csrf_token == "":
# Fall back to X-CSRFToken, to make things easier for AJAX,
# and possible for PUT/DELETE.
request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')
Второй тест не проходит, потому что это не запрос POST, а требуемая информация находится в request.DATA. Таким образом, кажется, что django не хочет принимать запрос PATCH. Как вы думаете, что было бы лучшим способом обойти это?
Вы бы порекомендовали использовать другую систему аутентификации (некоторые из них есть в документации Django-rest-framework)?
ИЗМЕНИТЬ2
Я нашел решение: я заметил, что просматриваемый API фактически отправляет запрос POST, но с параметром _method = "PATCH", поэтому я сделал то же самое с моим запросом ajax, и он отлично работает.
Я не знаю, правильно ли это сделать, любые отзывы и мнения приветствуются!
ИЗМЕНИТЬ3
Итак, прочитав больше, я обнаружил (я уже как бы знал ..), что, поскольку некоторые браузеры не поддерживают такие запросы, как PUT, PATCH, DELETE, можно отправить запрос на публикацию с помощью X-HTTP-Method-Override. в заголовке.
Итак, я думаю, что хороший способ сделать следующее:
$.ajax({
headers: {
'X-HTTP-Method-Override': 'PATCH'
},
type : "POST",
...
});