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

5

我希望创建一个Django自定义用户模型,以便我的用户可以使用电话或电子邮件登录。

这是我的建议解决方案

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

现在,当登录时,我可以像这样进行操作:

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

elif cleaned_data['email']:
   ...

我不确定是否可以将USERNAME_FIELD作为pk。 如果不行,我们可以很容易地使用UUIDField。

这个方案可行吗?

2个回答

9

对于电子邮件和手机号码的唯一性约束是不错的,同时我会设置 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

我认为这可以实现。让我知道吧!祝好。
最好的问候。

为什么我需要这样的登录流程?我在同一服务器上托管多个域,不同的客户要求不同的注册流程。 - Dev Aggarwal
好的。所以,用户可以选择使用电子邮件或电话注册,根据决定,他们将被重定向到特定的子域,该子域知道如何处理每种情况,然后您创建帐户,是这样吗?如果上述正确,那么登录如何管理?用户是否必须选择使用电子邮件或电话登录,然后被重定向到不同的子域来管理登录?这意味着您正在运行多个Django实例吗? - Marcos Schroh
不,我已经设置了'x'域具有电子邮件处理过程,而'y'域具有电话处理过程。现在当请求来自于'x'域时,我会向他们展示电子邮件注册页面。我已经在视图中解决了这个部分。 - Dev Aggarwal
是的,没错。你肯定需要编写自定义身份验证后端才能通过电子邮件或电话识别用户并登录他们。我以为你正在使用微服务方法,这就是为什么我问到了子域名的原因。所以这种方法可以行得通! :-) - Marcos Schroh
你所谈论的微服务方法是什么? - Dev Aggarwal
显示剩余5条评论

0
django login take two argoman : reqeust and user query so when we get this two things we can login. django authenticate searching in the user model and when user in found ....


def log_in(request):
if request.user.is_authenticated is True:
    return redirect('/home/')
if request.method == 'POST':

    u = request.POST.get('_phone_')
    p = request.POST.get('_pass1_')

    if '@' in u:
        user_check = authenticate(request, email=u, password=p)
    else:
        user_check = MyUser.objects.get(phone= u) # search in our model and find user with phone  


    if user_check is not None:

        user_check.last_login= datetime.now()
        user_check.save(update_fields=['last_login'])

        login(request, user_check)

        return redirect('/home/')

    else:
        return HttpResponse('bad request')
else:
    return render(request, 'login.html')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接