Тестовый вход пользователя DRF, ошибка неактивного пользователя
У меня есть вид для аутентификации:
class UserViewSet(viewsets.ViewSet):
@method_decorator(sensitive_variables("password"))
@action(url_path="sign-in", detail=False, methods=["POST"])
def sign_in(self, request: HttpRequest) -> Response:
if not request.user.is_anonymous:
return Response({"status": "forbidden"}, status=403)
form = AuthenticationForm(data=request.data)
print(form.data)
if form.is_valid():
user = authenticate(request, **form.cleaned_data)
login(request, user)
return Response({"status": "ok"}, status=200)
print(form.error_messages)
raise ValidationError(form.errors)
Я пишу тест:
class UserTest(TestCase):
@classmethod
def setUpClass(cls):
User.objects.create(username="admin", password="Qwerty1234", is_active=True)
super().setUpClass()
cls.client = Client()
@classmethod
def tearDownClass(cls):
return super().tearDownClass()
def test_sign_in(self):
url = "/api/sign-in/"
print(User.objects.get(username="admin").is_active)
response = self.client.post(
url,
data={"username": "admin", "password": "Qwerty1234"},
content_type="application/json",
)
Но я получаю ошибки от form form_validator:
{'invalid_login': 'Please enter a correct %(username)s and password. Note that both fields may be case-sensitive.', 'inactive': 'This account is inactive.'}
Что может быть проблемой?
P.S. Есть ли смысл в таком случае использовать sensitive_variables
?
мне кажется, что проблема заключается в хэшировании пароля, когда вы создаете пользователя напрямую, используя метод User.objects.create(username="admin", password="Qwerty1234", is_active=True)
, пароль не хэшируется, django хранит пароли в хэшированном формате, поэтому пароль должен быть установлен с помощью метода set_password
, поэтому нам нужно использовать set_password
, чтобы правильно хэшировать пароль, а затем сохранить пользователя после установки пароля
поэтому ваш viwe-код должен выглядеть следующим образом:
class UserViewSet(viewsets.ViewSet):
@method_decorator(sensitive_variables("password"))
@action(url_path="sign-in", detail=False, methods=["POST"])
def sign_in(self, request: HttpRequest) -> Response:
if not request.user.is_anonymous:
return Response({"status": "forbidden"}, status=403)
form = AuthenticationForm(data=request.data)
print(form.data)
if form.is_valid():
user = authenticate(request, **form.cleaned_data)
if user is not None:
login(request, user)
return Response({"status": "ok"}, status=200)
print(form.error_messages)
raise ValidationError(form.errors)
и ваш тестовый код должен выглядеть следующим образом:
class UserTest(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
user = User.objects.create(username="admin", is_active=True)
user.set_password("Qwerty1234")
user.save()
cls.client = Client()
@classmethod
def tearDownClass(cls):
return super().tearDownClass()
def test_sign_in(self):
url = "/api/sign-in/"
print(User.objects.get(username="admin").is_active)
response = self.client.post(
url,
data={"username": "admin", "password": "Qwerty1234"},
content_type="application/json",
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json(), {"status": "ok"})
sensitive_variables
используется для пометки определенных переменных как чувствительных, чтобы их значения не включались в отчеты об ошибках, что может быть полезно в производстве, чтобы избежать записи в журнал конфиденциальной информации, например паролей.
Надеюсь, это поможет вам.