django 可以通过电话或电子邮件登录

Dev*_*wal 3 django

我想创建一个 django 自定义用户模型,这样我就可以让我的用户使用电话或电子邮件登录。

这是我提出的解决方案

class ExtendedUser(AbstractBaseUser, PermissionsMixin):
    phonenumber = PhoneNumberField(unique=True, null=True ..)
    email = EmailField(unique=True, null=True ..)
    ...
    USERNAME_FIELD = 'pk'
Run Code Online (Sandbox Code Playgroud)

所以现在登录时,我可以做这样的事情

if cleaned_data['phonenumber']:
   u = User.objects.get(phonenumber=cleaned_data['phonenumber'])
   authenticate(username=u.pk, password=cleaned_data['password'])
   ...

elif cleaned_data['email']:
   ...
Run Code Online (Sandbox Code Playgroud)

我不确定是否可以把USERNAME_FIELDas pk。如果不可能,我们可以轻松地放置 UUIDField。

建议的解决方案好吗?

小智 5

电子邮件和电话的独特约束很好。另外,我会设置 USERNAME_FIELD = 'email'。

然后,我认为您应该尝试创建自定义身份验证后端。你可以在这里查看

就像 Django 所说:当有人调用 django.contrib.auth.authenticate() 时,Django 会尝试在其所有身份验证后端进行身份验证。

然后在您的自定义身份验证后端,您可以询问电子邮件或电话:

class CustomAuthenticationBackend:

    def authenticate(self, request, email_or_phone=None, password=None):
        try:
             user = User.objects.get(
                 Q(email=email_or_phone) | Q(phone=email_or_phone)
             )
             pwd_valid = user.check_password(password)
             if pwd_valid:            
                 return user
             return None
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
Run Code Online (Sandbox Code Playgroud)

我认为它可以工作。让我知道!!

此致。