Как я могу использовать два бэкенда аутентификации Django и предоставлять разный доступ в зависимости от того, какой из них используется?

У меня есть два различных класса пользователей для системы регистрации событий на основе Django. Назовем их "Регистрант" и "Сотрудник".

Эти два класса не являются взаимоисключающими, и я не вижу причин не использовать одну и ту же модель пользователя для обоих классов (с флагом для их различения).

Регистрант может войти в систему, подтвердив свою личность с помощью API третьей стороны, и затем зарегистрироваться на мероприятие.

Сотрудник имеет доступ к Django Admin и может управлять событиями. Я не доверяю стороннему API для достаточной аутентификации человека, имеющего доступ Staffer, поскольку, хотя он и запрашивает личную информацию для идентификации человека, он не запрашивает ничего такого надежного, как пароль. Поэтому я хочу, чтобы сотрудники вводили пароль вместо аутентификации через сторонний API.

<

К сожалению, хотя я знаю, что могу использовать несколько бэкендов аутентификации, я застрял, пытаясь понять, как это сделать:

a) определить, какой бэкенд аутентификации использовать (например, использовать бэкенд аутентификации регистратора во фронтенде и бэкенд аутентификации сотрудника в админке) b) разрешить только пользователям, аутентифицированным через Staffer auth backend, доступ к Admin

Может ли кто-нибудь указать мне правильное направление?

Прошу прощения за отсутствие кода; я переделываю систему авторизации с нуля (потому что предыдущая версия была очень плохо взломана) и не знаю, с чего начать.

EDIT: Есть некоторая полезная информация на Django Multiple Authentication Backends Based On Status, но поскольку я хочу использовать одну модель User для обоих классов пользователей, и оба auth backends будут запрашивать различные типы учетных данных (например, один запрашивает пароль, другой нет), мне нужно больше подумать о том, как решить эту проблему.

если у меня была такая проблема, я использовал наследуемую модель для каждого из них, делая имя пользователя логином по умолчанию для персонала и email для регистратора, расширяя обе модели BaseUser.

для выбора бэкенда Auth я просто устанавливаю флажок или создаю разные урлы для входа.

Ответ на вопрос "определить, какой бэкенд аутентификации использовать" довольно прост, вам просто не нужно этого делать. Как указано в документации, когда вы вызываете authenticate() функцию Django пробует каждую из AUTHENTICATION_BACKENDS по очереди, пока одна из них либо не вернет пользователя, либо не вызовет PermissionDenied исключение.

Кроме того, если вы посмотрите на код бэкенда по умолчанию [GitHub], если имя пользователя или пароль не переданы, он просто возвращает None. Вам нужно будет реализовать свой бэкенд аналогичным образом, чтобы, если ожидаемые вами учетные данные не передаются, вы просто возвращали None и позволяли другим (возможным) бэкендам справиться с этим.

Для "только разрешить пользователям, аутентифицированным через Staffer auth backend, доступ к Admin" вы можете определить сайт администратора по умолчанию и переопределить метод has_permission:

from django.contrib import admin
from django.contrib.auth import BACKEND_SESSION_KEY

class MyAdminSite(admin.AdminSite):
    def has_permission(self, request):
        """
        Return True if the given HttpRequest has permission to view
        *at least one* page in the admin site.
        """
        try:
            backend_path = request.session[BACKEND_SESSION_KEY]
            staffer_backend = backend_path == "path.to.StafferBackend"
            return request.user.is_active and request.user.is_staff and staffer_backend
        except KeyError:
            return False

А затем в apps.py в одном из ваших приложений:

from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'myproject.admin.MyAdminSite'

И наконец, в настройках замените 'django.contrib.admin' на

INSTALLED_APPS = [
    ...
    'myproject.apps.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...
]
Вернуться на верх