Получение ошибки отсутствия CSRF-токена на django rest framework (с TokenAuthentication) public APIView

У меня проблема с Django Rest Framework и конфигурациями CSRF. Я знаю, что есть много похожих постов на эту тему (например, этот Django Rest Framework remove csrf), но большинство из них не применимы (я не использую SessionAuthentication, ни шаблоны Django), и то, как DRF обрабатывает CSRF, все еще неясно для меня.

Вот ситуация :

  • У меня есть приложение DRF, действующее как бэкенд API с несколькими маршрутами, с аутентификацией по токену (JWT)
  • .
  • У меня также есть отдельный фронтенд, взаимодействующий с моим API. Оба находятся на одном домене (скажем https://example.com и https://example.com/backend)
  • .
  • У меня есть простой APIView на стороне DRF для регистрации, на который мне нужно посылать POST запросы. Это представление не требует аутентификации.

Когда я отправляю POST-запрос, я получаю 403 Forbidden error со следующим сообщением : detail "CSRF Failed: CSRF token missing or incorrect."

Вот мое мнение:

class RecaptchaVerifyView(APIView):
    permission_classes = []
    serializer_class = ReCaptchaSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            return Response({'success': True}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Я читал, что DRF отключает CSRF, за исключением SessionAuthentication, которую я не использую. Я также читал, что пустой permission_classes должен решить большинство проблем. Поэтому я думаю, что мне не нужно добавлять декоратор csrf_exempt (который я все равно безуспешно пробовал, btw).

Объявление маршрута в urls.py следующее:

urlpatterns = [
    ...
    path('recaptcha_verify/', RecaptchaVerifyView.as_view(), name='recaptcha_verify'),
    ...
]

Наконец, некоторые соответствующие настройки django:

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

...

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
}

Также я не уверен, что делать с настройками, связанными с CSRF, такими как SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, SESSION_COOKIE_NAME, CSRF_COOKIE_NAME, даже с самим CSRF middleware. Нужны они мне или нет

Из того, что я прочитал до сих пор, я думал, что мне не стоит беспокоиться о CSRF вообще, поскольку DRF применяет поведение Django по умолчанию, и я использую TokenAuthentication вместо SessionAuthentication.

Что я делаю не так?

P.S: У меня также есть другой публичный вид (страница входа), который работает нормально.

В настройке отсутствовала ключевая строка authentication_classes = () в дополнение к пустому списку permission_classes.

Итак, мой класс APIView теперь выглядит следующим образом :

class RecaptchaVerifyView(APIView):
    permission_classes = ()
    authentication_classes = ()

    @swagger_auto_schema(responses={status.HTTP_200_OK: openapi.Response("")})
    def post(self, request, *args, **kwargs):
        serializer = ReCaptchaSerializer(data=request.data)
        if serializer.is_valid():
            return Response({'success': True}, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

И то же самое для представления регистрации. Потратил на это несколько часов, но теперь это имеет смысл, поскольку в документации DRF говорится, что без явного объявления authentication_classes, по умолчанию применяется SessionAuthentication, что требует CSRF токена.

Вернуться на верх