Я знаю, что есть ответы по поводу Django Rest Framework, но я не смог найти решения своей проблемы.
У меня есть приложение с аутентификацией и некоторыми функциями. Я добавил к нему новое приложение, использующее Django Rest Framework. Я хочу использовать библиотеку только в этом приложении. Также я хочу сделать POST-запрос и всегда получаю такой ответ:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
У меня такой код:
# urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns(
'api.views',
url(r'^object/$', views.Object.as_view()),
)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from django.views.decorators.csrf import csrf_exempt
class Object(APIView):
@csrf_exempt
def post(self, request, format=None):
return Response({'received data': request.data})
Я хочу добавить API, не затрагивая текущее приложение. У меня вопрос: как отключить CSRF только для этого приложения?
django
django-rest-framework
csrf
django-csrf
Ирен Техас
источник
источник
Ответы:
Почему возникает эта ошибка?
Это происходит из-за
SessionAuthentication
схемы по умолчанию , используемой DRF. DRFSessionAuthentication
использует структуру сеанса Django для аутентификации, которая требует проверки CSRF.Когда вы не определяете их
authentication_classes
в своем представлении / наборе представлений, DRF использует эти классы аутентификации по умолчанию.Поскольку DRF должен поддерживать как сеансовую, так и несессионную аутентификацию для одних и тех же представлений, он обеспечивает проверку CSRF только для аутентифицированных пользователей. Это означает, что только аутентифицированные запросы требуют токенов CSRF, а анонимные запросы могут отправляться без токенов CSRF.
Если вы используете API в стиле AJAX с SessionAuthentication, вам необходимо включить действительный токен CSRF для любых «небезопасных» вызовов методов HTTP, таких как
PUT, PATCH, POST or DELETE
запросы.Что тогда делать?
Теперь, чтобы отключить проверку csrf, вы можете создать собственный класс аутентификации,
CsrfExemptSessionAuthentication
который расширяется отSessionAuthentication
класса по умолчанию . В этом классе аутентификации мы переопределимenforce_csrf()
проверку, которая происходила внутри фактическогоSessionAuthentication
.На ваш взгляд, тогда вы можете определить
authentication_classes
:Это должно обработать ошибку csrf.
источник
Более простое решение:
В views.py используйте фигурные скобки CsrfExemptMixin и authentication_classes:
источник
Измените urls.py
Если вы управляете своими маршрутами в urls.py, вы можете обернуть желаемые маршруты с помощью csrf_exempt (), чтобы исключить их из промежуточного программного обеспечения проверки CSRF.
В качестве альтернативы в качестве декоратора Некоторые могут найти использование декоратора @csrf_exempt более подходящим для своих нужд.
например,
должен получить работу выполненную!
источник
Для всех, кто не нашел полезного ответа. Да DRF автоматически снимает защиту CSRF, если вы не используете
SessionAuthentication
КЛАСС АУТЕНТИКАЦИИ, например, многие разработчики используют только JWT:Но проблема
CSRF not set
может быть вызвана другой причиной, например, вы неправильно добавили путь к просмотру:вместо того
источник
Я попробовал несколько ответов выше и почувствовал, что создание отдельного класса было немного за бортом.
Для справки, я столкнулся с этой проблемой при попытке обновить метод представления на основе функций до метода представления на основе классов для регистрации пользователя.
При использовании представлений на основе классов (CBV) и Django Rest Framework (DRF) выполните наследование от класса ApiView и установите свойства permission_classes и authentication_classes на пустой кортеж. Найдите пример ниже.
источник
Если вы не хотите использовать аутентификацию на основе сеанса, вы можете удалить
Session Authentication
из REST_AUTHENTICATION_CLASSES, и это автоматически удалит все проблемы на основе csrf. Но в этом случае API с возможностью просмотра может не работать.Кроме того, эта ошибка не должна возникать даже при аутентификации сеанса. Вы должны использовать пользовательскую аутентификацию, такую как TokenAuthentication, для своего API-интерфейса и обязательно отправлять
Accept:application/json
иContent-Type:application/json
(при условии, что вы используете json) в своих запросах вместе с токеном аутентификации.источник
Вам необходимо добавить это, чтобы предотвратить аутентификацию сеанса по умолчанию: (settings.py)
Затем: (views.py)
источник
Меня поражает та же проблема. Я последовал этой ссылке, и это сработало. Решение - создать промежуточное ПО
Добавьте файл disable.py в одно из ваших приложений (в моем случае это myapp)
И добавьте промежуточное ПО в MIDDLEWARE_CLASSES
источник
Мое решение показано ударом. Просто украсьте мой класс.
источник
При использовании сообщений REST API POST отсутствие заголовка запроса X-CSRFToken может вызвать эту ошибку. Документы Django предоставляют пример кода для получения и установки значения токена CSRF из JS.
Как указано в ответах выше, проверка CSRF происходит при использовании SessionAuthentication. Другой подход - использовать TokenAuthentication, но имейте в виду, что он должен быть помещен первым в списке DEFAULT_AUTHENTICATION_CLASSES настройки REST_FRAMEWORK.
источник
Если вы используете эксклюзивную виртуальную среду для своего приложения, вы можете использовать следующий подход без эффективных других приложений.
То, что вы наблюдали, происходит из-за того,
rest_framework/authentication.py
что вauthenticate
методеSessionAuthentication
класса есть этот код :Вы можете изменить
Request
класс, чтобы иметь вызываемое свойствоcsrf_exempt
и инициализировать его в соответствующем классе View,True
если вы не хотите проверять CSRF. Например:Затем измените приведенный выше код следующим образом:
Есть некоторые связанные изменения, которые вам нужно будет сделать в
Request
классеисточник
Это также может быть проблемой во время атаки DNS Rebinding .
В промежутках между изменениями DNS это также может быть фактором. Подождите, пока DNS не будет полностью очищен, решит эту проблему, если он работал до проблем / изменений DNS.
источник