'Best way to Implement Social authentication and 2FA in Django Rest Framework with custom User

I make a custom user model

class CustomUserManager(BaseUserManager):
    USER_TYPES = {
        'customer': "CUSTOMER",
        'admin': "ADMIN",
    }

    def _create_user(self, username, password, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        user = self.model(username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_customer(self, email_or_phone, password, slug, is_email, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        user_type, created = UserType.objects.get_or_create(name=self.USER_TYPES['customer'])
        extra_fields.setdefault('user_type', user_type)
        extra_fields.setdefault('slug', slug)
        username = email_or_phone
        if is_email:
            extra_fields.setdefault('email', email_or_phone)
        else:
            extra_fields.setdefault('phone', email_or_phone)
        return self._create_user(username, password, **extra_fields)

    def create_superuser(self, username, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_approved', True)
        extra_fields.setdefault('slug', "MYCOMPANY_SUPERUSER" + username.upper())
        extra_fields.setdefault('email', email)
        user_type, created = UserType.objects.get_or_create(name=self.USER_TYPES['admin'])
        extra_fields.setdefault('user_type', user_type)

        return self._create_user(username, password, **extra_fields)


class UserType(models.Model):
    """
    Stores a single user type entry with name, details and status,,,,,,,,.

    """
    USER_TYPE = (
        ('CUSTOMER', "customer"),
        ('VENDOR', 'vendor'),
        ('ADMIN', 'admin')
    )
    name = models.CharField(max_length=255, choices=USER_TYPE)
    detail = models.CharField(max_length=255, null=True, blank=True)
    status = models.BooleanField(default=True)

    def __str__(self):
        return self.name


class User(AbstractUser):
    """
    Stores a single user entry, related to :model:'user_type.UserType'
    """

    user_type = models.ForeignKey(UserType, on_delete=models.DO_NOTHING, related_name='type_user', null=True,
                                  blank=True)
    username = models.CharField(max_length=255, unique=True)
    email = models.EmailField(max_length=255, unique=True, null=True, blank=True)
    phone = models.CharField(max_length=255, unique=True, null=True, blank=True)
    slug = models.CharField(max_length=255)
    is_approved = models.BooleanField(default=False)
   

    USERNAME_FIELD = 'username'

    objects = CustomUserManager()

    def __str__(self):
        return "{}".format(self.username) + "-" + str(self.pk)

    def get_display_name(self):
        return "{}".format(self.username)

    def tokens(self):
        refresh_token = RefreshToken.for_user(self)
        tokens = {
            'refresh': str(refresh_token),
            'access': str(refresh_token.access_token)
        }
        return tokens

I use

djangorestframework-simplejwt

to social authentication I use

drf-social-oauth2

To implement 2FA after social authentication and normal login I try to use

django-two-factor-auth

I have two login panel

  1. Just log in using djangorestframework-simplejwt.
  2. Social authentication login panel using drf-social-oauth2.

My Question:

  1. Is that an excellent approach to do 2FA and social authentication along with Django Rest Framework?

  2. I need suggestions to implement 2FA in the Django rest framework with requirements I write in upper.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source