Nano Hash - криптовалюты, майнинг, программирование

Django Rest Framework, ajax POST работает, но PATCH выдает CSRF Failed: токен CSRF отсутствует или неверен

Я переношу свой проект в 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",
   ...
});

  • У меня была точно такая же проблема, и ваш EDIT3 дал мне решение. 20.11.2014

Ответы:


1

Наконец, я добавляю это как ответ.

Итак, прочитав больше, я обнаружил (я уже как бы знал ..), что, поскольку некоторые браузеры не поддерживают такие запросы, как PUT, PATCH, DELETE, можно отправить запрос на публикацию с помощью X-HTTP-Method-Override. в заголовке.

Итак, я думаю, что хороший способ сделать следующее:

$.ajax({
    headers: {
        'X-HTTP-Method-Override': 'PATCH'
    },
    type : "POST",
...
});
02.01.2015

2

Я также встречаю тот же вопрос, я узнаю из метода решения проблемы @overlii. Я использую веб-интерфейс django rest framework для выполнения put/patch и нахожу HTTP Request Headers информацию, как показано ниже: заголовки HTTP-запроса

На этом изображении мы можем найти заголовок X-CSRFTOKEN, поэтому я установил информацию заголовка ajax, как показано ниже:

$.ajax({
        headers: {
            'X-CSRFTOKEN': '{{ csrf_token }}'
        },
        type: "PATCH",
        dataType: "json",
        url: "/api/path/",
        data: "",
        success: function(data){
                
        }
});

Я использую этот способ для отправки запроса на исправление и обнаружил, что он работает правильно!

05.06.2018
  • Большое спасибо! Работает как часы! Я искал решение, но не мог найти нигде. При использовании глагола DELETE я устанавливал csrfmiddlewaretoken в поле данных, но он работал только с X-CSRFTOKEN в заголовках. Глагол POST обычно работает только с токеном de csrf в данных формы. Есть ли причина такого поведения? 03.07.2020

  • 3

    Это не прямое решение вашей проблемы, но это должно обеспечить некоторый контекст и обеспечить возможное решение.

    Django не поддерживает метод HTTP PATCH и отбрасывает все данные, включая токен CSRF. Возможный обходной путь — изменить метод на POST, заставить Django повторно обработать запрос и снова изменить метод. Это немного грязно, но работает, пример кода, используемый Django Piston предоставляется здесь:

    def coerce_put_post(request):
    """
    Django doesn't particularly understand REST.
    In case we send data over PUT, Django won't
    actually look at the data and load it. We need
    to twist its arm here.
    
    The try/except abominiation here is due to a bug
    in mod_python. This should fix it.
    """
    if request.method == "PUT":
        # Bug fix: if _load_post_and_files has already been called, for
        # example by middleware accessing request.POST, the below code to
        # pretend the request is a POST instead of a PUT will be too late
        # to make a difference. Also calling _load_post_and_files will result 
        # in the following exception:
        #   AttributeError: You cannot set the upload handlers after the upload has been processed.
        # The fix is to check for the presence of the _post field which is set 
        # the first time _load_post_and_files is called (both by wsgi.py and 
        # modpython.py). If it's set, the request has to be 'reset' to redo
        # the query value parsing in POST mode.
        if hasattr(request, '_post'):
            del request._post
            del request._files
    
        try:
            request.method = "POST"
            request._load_post_and_files()
            request.method = "PUT"
        except AttributeError:
            request.META['REQUEST_METHOD'] = 'POST'
            request._load_post_and_files()
            request.META['REQUEST_METHOD'] = 'PUT'
    
        request.PUT = request.POST
    

    Я успешно использовал это исправление (с некоторыми изменениями), и хотя оно кажется немного грязным, оно кажется очень полезным решением.

    В качестве альтернативы вы можете использовать перегрузку метода do в данных POST. Опять же, не самое красивое решение, но вполне работоспособное.

    Я хотел бы, чтобы кто-то предложил лучшее решение.

    29.09.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..