Что такое контроль доступа на основе ролей (RBAC)
Большинство приложений CRUD требуют некоторого уровня контроля доступа на основе ролей.
У вас может быть как минимум два типа пользователей.
- Пользователь повышенного разрешения (Admin, root или Superister)
- Нормальный пользователь aka все остальные;)
Более вероятно, у вас есть больше уровней между.
Это означает только пользователи с определенными роль может получить доступ к определенным конечным точкам API или операции E.g. Разрешить всем Получить
Операция, но только админ
может УДАЛЯТЬ
. Некоторые уровни между ними могут создавать/обновить и т. Д.
Код
Следующий код предполагает ваш Пользователь
Модель имеет роль
атрибут. Лучше иметь значение по умолчанию, чтобы каждый созданный пользователем запустился С наименьшим уровнем, даже если роль не назначается при создании.
Давайте сначала определим Rolechecker
класс следующим образом:
class RoleChecker: def __init__(self, allowed_roles: List): self.allowed_roles = allowed_roles def __call__(self, user: User = Depends(get_current_active_user)): if user.role not in self.allowed_roles: logger.debug(f"User with role {user.role} not in {self.allowed_roles}") raise HTTPException(status_code=403, detail="Operation not permitted")
Затем в ваших маршрутах файл используйте его следующим образом:
allow_create_resource = RoleChecker(["admin"]) @router.post( "/some-resource/", response_model=schemas.MyResource, status_code=201, dependencies=[Depends(allow_create_resource)], ) def add_resource(resource: schemas.ResourceCreate, db: Session = Depends(get_db)): # Some validation like resource does not already exist # Create the resource pass
Иногда вы хотите разрешить несколько ролей для выполнения определенной операции. Вот почему, Rolechecker
принимает список ролей, как:
allow_create_resource = RoleChecker(["admin", "manager"])
Обучение (или как я получил сюда)
Если вы пришли сюда, просто ищу решение, вы можете перестать читать сейчас.
Читайте, узнать, как я добрался до решения, вещи, которые я пробовал (и потерпел неудачу)
(Иногда такие детали дают вам представление о том, что вы можете захотеть в будущем)
Как вы можете знать, вы можете получить текущие детали пользователей в API через Инъекция зависимости через Пользователь: (get_current_user)
Смотрите документация
Так просто первая попытка была на линии
if user.role not 'admin': raise HTTPException(status_code=403, detail="Operation not permitted")
Я расширил вышесказанный к user.role не в [«admin», "Manager"]
Разрешить Несколько ролей для выполнения этой работы.
Работает для «доказательства концепции», но мы не можем добавлять похожий код где угодно
Тогда я создал
def verify_role(required_role: List, user: User = Depends(get_current_active_user)): if user.role not in required_role: raise HTTPException(status_code=403, detail="Operation not permitted")
Мне нужно было пройти список ролей к функции. К сожалению, я не мог Позвоните это через Зависит ...| Отказ Я продолжал получать
В зависимости нет атрибута … ошибка.
Кроме того, мне нужно называть это из Маршрутизатор
Функция декоратора как Зависимости = [зависит (my_func)]
а не в функции param Как Пользователь: (get_current_user)
Наконец, другой пользователь указывал мне на Это Раздел документации, и это было так. 🎉
Спасибо
Я благодарен за Marcelo Aka Kludex. и Дэнни Рохда на Fastapi Gitter для идей и помощи.
Оригинал: “https://dev.to/mandarvaze/how-to-implement-role-based-access-control-with-fastapi-488n”