Конфликт разрешений Django Rest Framework

#python #django #permissions #django-rest-framework

#python #django #разрешения #django-rest-framework

Вопрос:

У меня возникли небольшие проблемы с пониманием процесса аутентификации и разрешения Django Rest Framework. Мой REST_FRAMEWORK диктант в settings.py заключается в следующем:

 # Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
    'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],

'DEFAULT_AUTHENTICATION_CLASSES': (
#     # 'rest_framework.authentication.BasicAuthentication',
#     # 'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.TokenAuthentication',
),
  

Сейчас я пытаюсь сделать так, чтобы вызовы users-list or users-detail могли выполнять только аутентифицированные пользователи, но мне нужны пользователи, не прошедшие проверку подлинности, чтобы иметь возможность совершать звонки на users-create . Я попробовал следующее, используя rest_condition :

 from rest_condition import Or, And, Not
class UserViewSet(ListOnlyIfAdminMixin, viewsets.ModelViewSet):
    queryset = U.objects.all()
    serializer_class = UserSerializer
    # Would this permission_classes declaration come before or be overridden by
    #   the decorator below?
    # permission_classes = [IsAuthenticated, IsAdminOrTargetUser,]

    @permission_classes([Or(Not(IsAuthenticated), IsAdminUser)])
    def create(self, request, *args, **kwargs):
         # stuff
  

Но когда я пытаюсь сделать POST запрос к /api/users с нужной информацией для создания нового пользователя, я получаю обратно следующее:

 {
detail: "Authentication credentials were not provided."
}
  

Теперь, очевидно, что учетные данные для аутентификации не могут быть предоставлены, поскольку у пользователя еще нет учетной записи или токена. Как можно разрешить пользователю зарегистрироваться, не требуя уже учетных данных?

Ответ №1:

Здесь вы можете увидеть порядок установки разрешения для определенного метода.

Таким образом, вы можете видеть, что находитесь на правильном пути, задав разрешения только для функции create. Однако я не понимаю, зачем вам нужно выполнять rest_condition для вашего разрешения: простого Not (IsAuthenticated), чтобы переопределить настройки по умолчанию, было бы достаточно.

Комментарии:

1. Перечитывая документы, кажется, что разрешения на уровне метода могут быть только более ограничительными , чем разрешения на уровне представления — с чем, я думаю, я боролся. Правильно ли это звучит?

2. Да, кажется, это правильно. Таким образом, правильным способом решения этой проблемы, вероятно, было бы установить разрешения для каждого метода в соответствии с вашими потребностями.

3. Или вы можете использовать пользовательский класс разрешений для своего представления: если методом запроса является POST (сопоставленный с create), разрешить для любых пользователей; в противном случае разрешить только для аутентифицированных пользователей, которым принадлежит учетная запись или администраторы. Ссылка

4. В итоге я написал мета-мета-класс, который генерирует мета-классы, которые я бы назначил рассматриваемому набору представлений, чтобы украсить функции метода функциями разрешений, которые я передаю при объявлении. Сложный, но превосходный пользовательский интерфейс и работает отлично.

5. Верно ли также, что разрешения на уровне объекта и представления могут быть только более ограничительными, чем глобальные разрешения, определенные в settings.py ? Я продолжал получать ошибку, пока не прокомментировал разрешения, чтобы я мог определить их для каждого вида и для каждого объекта.