Как проверить наличие CSRF в APIView (DRF)?

У меня есть API, с JSON в качестве content-type, построенный с помощью Django Rest Framework. Есть конечная точка, которая разрешает вход пользователей, для этого я использую пакет simple-jwt, и как представление имеет permission_classes = [AllowAny] и работает через POST метод, чтобы сделать вход, поэтому я добавил CSRF token к этому представлению:

@method_decorator(csrf_protect, name='post')
class TokenCookieObtainPairView(TokenObtainPairView):
    ...

Когда заголовок и cookie, имеющие CSRF, не совпадают, шаблон django (views.csrf.csrf_failure) возвращает статус 403, но я переопределил это (метод finalize_response()), чтобы вернуть сообщение потребителю.

if response.status_code == status.HTTP_403_FORBIDDEN:
    serializer = MessageSerializer({'message': self.MESSAGE})
    new_response = Response(serializer.data, status=status.HTTP_403_FORBIDDEN)
    return super().finalize_response(request, new_response, *args, **kwargs)

Я создал тест для этого представления. Я использую pytest и APIClient из DRF.

from pytest import mark, fixture

@fixture
def api_client_csrf() -> APIClient:
    return APIClient(ensure_csrf_checks=True)

@mark.django_db
def test_login_view_csrf(api_client_csrf):
    """Verify that the 'login' view need the CSRF_token."""
    path = reverse_lazy('login')
    credentials = {
        'email': 'xxx@yyyy.com',
        'password': '******'
    }
    response = api_client_csrf.post(path, data=credentials)
    print(response.data)
    assert response.status_code == 403

Тест не прошел, потому что CSRF-токен не требуется и учетные данные недействительны, поэтому pytest возвращает:

assert response.status_code == 403
E       assert 401 == 403
E         +401
E         -403

В документации DRF Testing APIClient CSRF validation говорится:

Как обычно, проверка CSRF будет применяться только к любым аутентифицированным в сеансе представления. Это означает, что проверка CSRF будет происходить только в том случае, если клиент вошел в систему, вызвав функцию login().

Но мой тест предназначен для представления, которое выполняет вход в систему, и это причина AllowAny в классе разрешения.

Есть ли способ проверить мое представление, когда нет CSRF-токена?

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

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