DRF 如何:在没有 USERNAME_FIELD 的情况下进行简单 jwt 身份验证

Drf how to: simple-jwt authenticating without the USERNAME_FIELD

我已经扩展了 TokenObtainPairSerializer,我的用户模型将电子邮件作为 USERNAME_FIELD 但是这种类型的用户没有电子邮件,而是我想使用自动生成的唯一 ID 来代替身份验证电子邮件。

class MyTokenStudentSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        user = authenticate()(
            student_id=attrs['student_id'], password=attrs['password'])
        if user is not None:
            if user.is_active:
                data = super().validate(attrs)
                refresh = self.get_token(self.user)
                refresh['student_id'] = self.user.student_id
                try:
                    data["refresh"] = str(refresh)
                    data["access"] = str(refresh.access_token)
                    data['student_id'] = self.user.student_id
                    data['firstname'] = self.user.firstname
                    data['middlename'] = self.user.middlename
                    data['lastname'] = self.user.lastname
                    data['phone'] = self.user.phone
                    data['last_login'] = self.user.last_login
                    data['joined_date'] = self.user.joined_date
                except Exception as e:
                    raise serializers.ValidationError(
                        {'error': 'Something Wrong!'})
                return data
            else:
                raise serializers.ValidationError(
                    {'error': 'Account is not activated'})
        else:
            raise serializers.ValidationError({
                'error': 'Incorrect student id and password combination!'})

即使我没有传递电子邮件字段,这需要电子邮件和密码,我如何让它使用 student_id 而不是电子邮件。

您可以按如下方式覆盖 username_field

另外请小心使用 PasswordField,它默认会去除空格。您绝对不希望 password 有效。

from rest_framework import serializers
rest_framework_simplejwt.serializers import PasswordField
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class MyTokenStudentSerializer(TokenObtainPairSerializer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['student_id'] = serializers.CharField(required=False)
        self.fields['password'] = PasswordField(trim_whitespace=False)

    username_field = 'student_id'
    auth_fields = ['student_id']