使用电子邮件而不是用户名获取身份验证令牌

时间:2019-01-06 23:06:40

标签: django django-rest-framework

我正在尝试使用电子邮件而不是用户名来获取身份验证令牌,我已更改了序列化以仅接受电子邮件,但我认为我有问题。

class AuthTokenSerializer(serializers.Serializer):
    """Serializer for user authentication object"""

    email_or_username = serializers.CharField()
    password = serializers.CharField(style = {'input_type' : 'password' }, trim_whitespace = False)

    def validate(self, attrs):
        """Validate and authentiate the user"""

        email_or_username = 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(msd, code='authorization')

        attrs['user'] = user

        return attrs

和视图

class LoginViewSet(viewsets.ViewSet):
    """Check email and password and returns an auth token."""

    serializer_class = serializers.AuthTokenSerializer
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

    def create(self, request):
        """Use the ObtainAuthToken APIview to validate and create a token."""

        return ObtainAuthToken().post(request)

我进行考试时

def test_create_token_for_user(self):
    """Test that a token is created"""

    parametrs = {'email' : 'test@noah-lc.com','email' : 'test@noah-lc.com', 'name' : 'test', 'password' : 'testPASS@123'}
    create_user(**parametrs)
    res = self.client.post(TOKEN_URL, parametrs)
    print(res.data)
    self.assertIn('token', res.data)
    self.assertEqual(res.status_code, status.HTTP_200_OK)

我收到此错误

  

AssertionError:在{'username':[ErrorDetail(string ='此字段是必填字段。',code ='required')')}}中找不到'token'

自己用户的模型

class UserProfile(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'

并设置

AUTH_USER_MODEL = 'core.UserProfile'

2 个答案:

答案 0 :(得分:1)

DRF的ObtainAuthToken使用其AuthTokenSerializer,后者期望用户名而不是电子邮件。因此,如果您想使用电子邮件,我建议您创建自己的ObtainAuthToken视图,甚至最好将ObtainAuthToken的逻辑直接放入您的LoginViewSet中,因为它似乎可以起到相同的作用目的。您可以让他们创建一个自定义AuthTokenSerializer来接受电子邮件(而不是用户名或两者兼有)并与之一起使用

答案 1 :(得分:0)

我想您有一个名为用户的应用,然后在此处定义新的用户模型,

class User(AbstractBaseUser, PermissionMixin):

    first_name = models.CharField(max_length=100, blank=True, null=True)
    last_name = models.CharField(max_length=100, blank=True, null=True)
    email = models.EmailField(db_index=True, unique=True)

    USERNAME_FIELD = 'email'

重要的是USERNAME_FIELD,它设置电子邮件而不是用户名

然后在settings.py中添加以下行

AUTH_USER_MODEL = 'users.User'