Как иметь разные страницы входа для одной модели аутентификации в Django?
У меня одна модель пользователя Django (с пользовательским менеджером пользователей), но два разных типа пользователей, а именно Store и Customer, для обработки аутентификации:
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.')})
Теперь магазины и клиенты должны использовать два разных сайта для входа в систему, т.е. магазины будут использовать admin.domain.com, а клиенты будут просто использовать domain.com. Если магазин вошел в admin.domain.com, будет ли он также показывать, что он вошел в систему, когда он посещает domain.com? Если да, то как я могу предотвратить это и изолировать эти две модели для конкретных сайтов, используя при этом одну и ту же модель и методы аутентификации?
Создайте 2 миксина StoreUserOnlyMixin и CuustomerUserOnlyMixin, наследующих от класса django TemplateView. Затем в каждом из них переопределите метод dispatch.
from django.views.generic import TemplateView
from django.contrib import auth
from django.http import HttpResponseRedirect
from django.urls import reverse
class CustomerUserOnlyMixin(TemplateView)
def dispatch(self, *args, **kwargs):
if not self.request.user.is_customer():
auth.logout(self.request)
return HttpResponseRedirect(reverse('customer_login_view'))
return super(CustomerUserOnlyMixin, self).dispatch(*args, **kwargs)
И нечто подобное с StoreUserOnlyMixin. После этого вы можете наследоваться от одного из них, основываясь на том, должно ли представление быть доступно для Store или Customer
Для решения вышеуказанной задачи можно использовать permission_classes.
DRF имеет атрибут permission_classes, который поддерживает список классов разрешений.
Создайте 2 класса разрешений IsShopUser и IsShopCustomer. Оба класса будут дочерними для класса IsAuthenticated, который создан в 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
"""
в каждом представлении применяются эти классы разрешений, основанные на типе пользователя.
class ShopAPIView(APIView):
permission_classes = [ISShopUser]
Не рекомендуется выводить пользователей из системы, если они вводят неправильный API. Достаточно просто показать ошибку.