Как реализовать двойную аутентификацию (по электронной почте и номеру телефона) в 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',
    ),
}

Панель администратора

enter image description here

Вернуться на верх