Как реализовать двойную аутентификацию (по электронной почте и номеру телефона) в Django Rest Framework?
Я создаю приложение Django Rest Framework (DRF), и мне нужно реализовать двойную аутентификацию, позволяющую пользователям входить в систему, используя либо электронную почту, либо номер мобильного телефона. Как лучше всего это реализовать?
Я уже настроил систему аутентификации с использованием электронной почты, но теперь мне нужно расширить ее для поддержки аутентификации по мобильному номеру. Должен ли я создать собственный бэкэнд аутентификации, или есть пакет DRF, который поможет мне достичь этого проще?
Буду признателен за любые советы или примеры того, как реализовать двойную аутентификацию в DRF. Спасибо!
Вы можете архивировать аутентификацию с помощью (email or mobile)
, переопределив модель User следующим образом
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
mobile = models.CharField(max_length=20,unique=True)
views.py
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
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)
Signin ApiView
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)
settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}