我正在构建 Django Rest Framework (DRF) 应用程序,我需要实现双重身份验证,允许用户使用电子邮件或手机号码登录。实现这一点的最佳方法是什么?
我已经使用电子邮件设置了身份验证系统,但现在我需要扩展它以支持手机号码身份验证。我应该创建一个自定义身份验证后端,还是有一个 DRF 包可以帮助我更轻松地实现这一目标?
如果您提供有关如何在 DRF 中实现双重身份验证的建议或示例,我将不胜感激。谢谢!
您可以使用
(email or mobile)
通过重写用户模型来存档身份验证,如下所示
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
mobile = models.CharField(max_length=20)
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import CustomUser
from django.db.models import Q
from django.contrib.auth.hashers import check_password
from django.contrib.auth import login
### Authentication handler
def authenticate(email_or_mobile,password):
user = CustomUser.objects.filter(Q(email=email_or_mobile) | Q(mobile=email_or_mobile)).first()
if user:
is_user = check_password(password,user.password)
if is_user:
return user
else: None
else:
return None
### admin.py
```python
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import gettext as _
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name','mobile')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', )}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('first_name', 'last_name', 'email', 'password1', 'password2'),
}),
)
list_display = ('id','email','mobile', 'first_name', 'last_name',
'is_active', 'is_staff')
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
admin.site.register(CustomUser, CustomUserAdmin)
class SigninApiView(APIView):
def post(self,request):
email_or_mobile = request.POST.get('email_or_mobile')
password = request.POST.get('password')
user = authenticate(email_or_mobile,password)
if user is not None:
login(request,user)
return Response({'status':True,'message':'Login success'},status=status.HTTP_200_OK)
else:
return Response({'status':False,'message':'Invalid Credentials!'},status=status.HTTP_400_BAD_REQUEST)
AUTH_USER_MODEL = 'myapp.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}