Авторизация на уровне объекта в наборе Django Rest Framework - PullRequest
2 голосов
/ 03 апреля 2020

Я создаю API с Django Rest Framework (DRF) и задаюсь вопросом, где мне следует обрабатывать авторизацию на уровне объекта.

До сих пор я создал модель Organization и пользовательскую модель пользователя. с электронной почтой, являющейся уникальным идентификатором вместо имени пользователя. Организации и пользователи в настоящее время связаны через поле «многие ко многим».

Что я хотел бы сделать, так это убедиться, что когда пользователь нажимает на мой API, он может выполнять только стандартные действия CRUD над модели, которые связаны с пользователями соответствующей организации. В качестве примера вот мой текущий UserViewSet, где я переопределил метод get_queryset, чтобы отфильтровать набор запросов User и вернуть только тех пользователей, которые принадлежат к той же организации, что и пользователь, вызывающий API:

class UserViewSet(viewsets.ModelViewSet):
    serializer_class = UserSerializer

    def get_queryset(self):
        User = get_user_model()
        user = self.request.user
        organizations = user.organization.all()
        return User.objects.filter(organization__in=organizations)

Что считается наилучшей практикой для распространения этих ограничений на другие действия набора? Например, если я хочу убедиться, что пользователь может только создавать и добавлять других пользователей в организации, с которыми он связан, я должен переопределить метод create в наборе и выполнить проверку там, что организация, которая была передана в запросе данные совпадают с организацией, к которой принадлежит пользователь, вызывающий API?

У меня такое чувство, что я бы в итоге нарушил DRY, потому что я бы переопределил все просмотр действий и повторение почти идентичных переопределений. Эта интуиция не так? Я думаю, я мог бы разделить «проверки» в отдельный файл services.py и вызывать их в переопределенных действиях. Должен ли я вместо этого разгрузить эти проверки для пользовательских разрешений? Или я должен полностью игнорировать представления и поместить проверку в сериализаторы?

1 Ответ

1 голос
/ 05 апреля 2020

На самом деле вам нужны разные инструменты для разных действий DRF CRUD. Лично я люблю использовать rules пакет

  • name=XXX-list: /XXX/
    • list: разрешения через get_queryset() фильтрация
    • create: разрешения посредством rules и проверки полезной нагрузки с serializer
  • name=XXX-detail: /XXX/{id}
    • retrieve: разрешения через get_queryset() фильтрация
    • partial_update, update и destroy: разрешения через rules и get_queryset() фильтрация

Возможно, вам потребуется написать собственный класс DjangoObjectPermission для интеграции rules

...