Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-authentication

How to have different login pages for same authentication model in Django?


I have one Django user model (with a custom user manager) but two different user types, namely Store and Customer, to handle authentication:

authentication/models.py

class User(AbstractBaseUser, PermissionsMixin):
    ...

    # checks if user is associated with a store object
    def is_store(self):
        return hasattr(self, 'store')

    # checks if user is associated with a customer object
    def is_customer(self):
        return hasattr(self, 'customer')

stores/models.py

class Store(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.RESTRICT, primary_key=True)
    ...

    def clean(self):
        # validates that the selected user doesn't belong to a customer object
        if self.user.is_customer():
            raise ValidationError({'user': _('This user is already associated with a customer.')})

customers/models.py

class Customer(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.CASCADE, primary_key=True)
    ...

    def clean(self):
        # validates that the selected user doesn't belong to a store object
        if self.user.is_store():
            raise ValidationError({'user': _('This user is already associated with a store.')})

Now, the stores and customers should use two different websites to login in i.e. stores will use admin.domain.com while customers will simply use domain.com. If a store is logged into admin.domain.com, will it also show that he is logged in when he visits domain.com? If so, how can I prevent this and isolate these two models to specific sites, while using the same authentication model and methods?


Solution

  • One can use permission_classes to accomplish above problem.

    DRF has permission_classes attribute which supports list of permission class . Create 2 permission classes IsShopUser and IsShopCustomer. Both class will be child of IsAuthenticated class which is build in DRF.

    from rest_framework.permissions import IsAuthenticated
    class ISShopUser(IsAuthenticated):
        def has_permission(self, request, view):
            """
            if user is a shop user return true
            else return false
            """
    

    in each view apply, those permission classes based on user type.

    class ShopAPIView(APIView):
        permission_classes = [ISShopUser]
    

    It is not recommended to log out users if they enter the wrong API. Simply show an error.