首页 > 解决方案 > 验证返回 None 而不是 user

问题描述

我目前正在开发我的Django应用程序。场景是我创建了一个自定义用户模型。我的用户模型的代码如下:

...
class User(AbstractBaseUser, PermissionsMixin):
    """Custom user model that supports using email instead of username"""
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    is_active = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'

我定制了User模型以根据email用户名而不是用户名来验证用户。我之前已经这样做了,但不知道我什么时候尝试对用户进行身份验证以token使其返回None。我在这里使用rest_framework.authtokenTokenAuthentication 这是我的序列化程序代码:

...
class AuthTokenSerializer(serializers.Serializer):
    """Serializer for the user authentication object"""
    email = serializers.CharField()
    password = serializers.CharField(
        style={'input_type': 'password'},
        trim_whitespace=False
    )

    def validate(self, attrs):
        """Validate and authenticate the user"""
        email = attrs.get('email')
        password = attrs.get('password')

        user = authenticate(
            request=self.context.get('request'),
            username=email,
            password=password
        )
        if not user:
            msg = _('Unable to authenticate with provided credentials')
            raise serializers.ValidationError(msg, code='authentication')

        attrs['user'] = user
        return attrs

哼!感谢断点。我已经弄清楚实际错误发生在哪里。我发现authenticate()它总是返回一个错误,None而不是返回一个用户对象,即使所有凭据都是正确的。

注意:我已经authenticate使用电子邮件和用户名这两个参数进行了测试。

而且,我已经自定义了 BaseUserManager 类并使用我的 create_user() 方法覆盖以创建自定义用户:

def create_user(self, email, password=None, **kwargs):
        """To create user using an email instead
            of username"""
        if not email:
            raise ValueError('Invalid Email!!')
        user = self.model(email=self.normalize_email(email), **kwargs)
        user.set_password(password)
        user.save(using=self._db)

        return user

这是我的代码每次都失败的TestCase。

def test_create_token_for_user(self):
        """Test that a token is created for the user"""
        payload = {'email': 'test@domain.com', 'password': 'testpass'}
        create_user(**payload)
        res = self.client.post(TOKEN_URL, payload)

        self.assertIn('token', res.data)
        self.assertEqual(res.status_code, status.HTTP_200_OK)

它说token not found in ....。这是因为 authenticate() 函数返回 None 而不是用户对象。

标签: pythondjangodjango-rest-framework

解决方案


谢谢@harryghgim 帮助我。现在基本解决了错误,使用该authenticate()功能时有一个概念。它返回 None 如果user.is_active = Falseis_active当您要使用身份验证时,请确保您的值为 True。它仅适用于活跃用户。


推荐阅读