简体   繁体   English

登录测试期间身份验证失败

[英]Authentication fails during login testing

I am trying to test custom login (with pytest) but authentication fails returning None.我正在尝试测试自定义登录(使用 pytest),但身份验证失败返回无。 Here is views.py这是views.py

from rest_framework.authtoken.views import ObtainAuthToken
from my_auth.api.serializers import UserLoginSerializer

class LoginAuthToken(ObtainAuthToken):
    serializer_class = UserLoginSerializer

serializers.py序列化程序.py

from django.contrib.auth import authenticate
from django.utils.translation import gettext_lazy as _

from rest_framework import serializers
from rest_framework.authtoken.serializers import AuthTokenSerializer


class UserLoginSerializer(AuthTokenSerializer):
    username = None
    email = serializers.EmailField(
        label=_("Email"),
    )

    def validate(self, attrs):
        email = attrs.get('email')
        password = attrs.get('password')
        if email and password:
            user = authenticate(request=self.context.get('request'),
                                email=email, password=password)  # returns None

            if not user:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg, code='authorization')  # raises
        else:
            msg = _('Must include "email" and "password".')
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

tests.py测试.py

import pytest

from django.urls import reverse

from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient


@pytest.fixture
def test_user():
    user = MyUser.objects.create(
        email='test@m.com',
        first_name='Firstname',
        last_name='Lastname'
    )
    user.set_password('pass5678')
    return user


@pytest.mark.django_db
def test_login(test_user):
    client = APIClient()
    response = client.post(
        path=reverse('login'),
        data={
            'email': 'test@m.com',
            'password': 'pass5678',
        },
        format='json',
    )
    assert(response.status_code == status.HTTP_200_OK)
    token = Token.objects.get(user=test_user)
    assert(token.key == response.data['token'])

Terminal output:端子 output:

========================================================================================================== test session starts ==========================================================================================================
platform linux -- Python 3.8.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
django: settings: news_project.settings (from ini)
rootdir: /home/andrei/NEWS/news_project, configfile: pytest.ini
plugins: lambda-1.2.4, Faker-8.4.0, common-subject-1.0.5, assert-utils-0.2.2, drf-1.1.2, fixture-order-0.1.3, django-4.3.0
collected 2 items                                                                                                                                                                                                                       

my_auth/tests.py F                                                                                                                                                                                                                [ 50%]
news/tests.py .                                                                                                                                                                                                                   [100%]

=============================================================================================================== FAILURES ================================================================================================================
______________________________________________________________________________________________________________ test_login _______________________________________________________________________________________________________________

test_user = <MyUser: test@m.com>

    @pytest.mark.django_db
    def test_login(test_user):
        client = APIClient()
        response = client.post(
            path=reverse('login'),
            data={
                'email': 'test@m.com',
                'password': 'pass5678',
            },
            format='json',
        )
>       assert(response.status_code == status.HTTP_200_OK)
E       assert 400 == 200
E        +  where 400 = <Response status_code=400, "application/json">.status_code
E        +  and   200 = status.HTTP_200_OK

my_auth/tests.py:78: AssertionError
----------------------------------------------------------------------------------------------------------- Captured log call -----------------------------------------------------------------------------------------------------------
WARNING  django.request:log.py:224 Bad Request: /api/auth/login/
======================================================================================================== short test summary info ========================================================================================================
FAILED my_auth/tests.py::test_login - assert 400 == 200
====================================================================================================== 1 failed, 1 passed in 3.63s ====================================================================================================== 

This is output when I do print(response.data) in test_login当我在 test_login 中执行print(response.data)时,这是 output

{'non_field_errors': [ErrorDetail(string='Unable to log in with provided credentials.', code='authorization')]}

At first I thought that rest_framework.request.Request object is not passed to the UserLoginSerializer's validate(), but it is actually.一开始我以为rest_framework.request.Request object没有传递给UserLoginSerializer的validate(),但实际上是这样。 Moreover, it's almost the same as the Request obtained when I send POST request via Postman.此外,它与我通过 Postman 发送 POST 请求时获得的请求几乎相同。 What am I missing?我错过了什么?

You still need to call save the user after calling set_password :调用set_password后,您仍然需要调用save the user :

@pytest.fixture
def test_user():
    user = MyUser.objects.create(
        email='test@m.com',
        first_name='Firstname',
        last_name='Lastname'
    )
    user.set_password('pass5678')
    user.save()
    return user

https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#django.contrib.auth.models.User.set_password https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#django.contrib.auth.models.User.set_password

Sets the user's password to the given raw string, taking care of the password hashing.将用户的密码设置为给定的原始字符串,注意密码散列。 Doesn't save the User object.不保存用户 object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM