Как проверить наличие 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-токена?
Я прочитал этот вопрос, поэтому я думаю, что это возможно, но возможно разработчик здесь ошибается.