Официальная оригинальная ссылка
Эта серия статей адрес github
Пожалуйста, укажите источник
разрешение
Наряду с проверкой подлинности и регулированием разрешение определяет, следует ли принять или отклонить запрос на доступ.
Проверки разрешений всегда выполняются в самом начале представления, прежде чем разрешается выполнение любого другого кода. Проверка разрешений обычно выполняется с помощьюrequest.user
иrequest.auth
Информация об аутентификации в свойствах, чтобы определить, разрешать ли входящие запросы.
Разрешения используются для предоставления или отказа в доступе различным классам пользователей к различным частям API.
Самое простое разрешение — разрешить доступ для пользователей, прошедших проверку подлинности, и запретить доступ пользователям, не прошедшим проверку подлинности. Это соответствует структуре REST вIsAuthenticated
своего рода.
Чуть более разрешительные разрешения обеспечивают полный доступ для пользователей, прошедших проверку подлинности, и доступ только для чтения для пользователей, не прошедших проверку подлинности. Это соответствует структуре REST вIsAuthenticatedOrReadOnly
своего рода.
Как определить разрешения
Разрешения в среде REST всегда определяются как список классов разрешений.
Проверьте каждое разрешение в списке перед запуском принципала представления. Возникает, если какая-либо проверка разрешений не удаласьexceptions.PermissionDenied
илиexceptions.NotAuthenticated
исключение, и тело представления больше не будет запускаться.
В случае сбоя проверки разрешений будет возвращен ответ «403 Forbidden» или «401 Unauthorized» в соответствии со следующими правилами:
- Запрос был успешно аутентифицирован, но разрешение было отказано.- Возвращает 403 Запрещенный ответ.
- Запрос не был успешно аутентифицирован, и класс аутентификации с наивысшим приоритетом не был добавлен.
WWW-Authenticate
заголовок.— вернет ответ 403 Forbidden. - Запрос не был успешно аутентифицирован, но добавлен класс аутентификации с наивысшим приоритетом
WWW-Authenticate
заголовок.— возвращает ответ HTTP 401 Unauthorized с соответствующимWWW-Authenticate
заголовок.
Разрешения на уровне объекта
Разрешения инфраструктуры REST также поддерживают разрешения на уровне объектов. Разрешения на уровне объекта используются для определения того, разрешено ли пользователю работать с конкретным объектом, обычно с экземпляром модели.
.get_object()
При вызове разрешения на уровне объекта применяются с помощью общих представлений среды REST. Как и в случае с разрешениями на уровне просмотра, если пользователю не разрешено работать с данным объектом,exceptions.PermissionDenied
аномальный.
Если вы пишете свое собственное представление и хотите применить разрешения на уровне объекта или если вы переопределили общее представлениеget_object
метод, вам нужно будет явно вызвать, когда вы извлекаете объект.check_object_permissions(request, obj)
метод.
Это приведет кPermissionDenied
илиNotAuthenticated
исключение или просто возврат, если представление имеет соответствующие разрешения.
Например:
def get_object(self):
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
self.check_object_permissions(self.request, obj)
return obj
Разрешения на уровне объекта
Из соображений производительности общие представления не применяют автоматически разрешения на уровне объектов к каждому экземпляру в наборе запросов при возврате списка объектов.
Как правило, когда вы используете разрешения на объект на уровне объектов, вам также необходимо правильно отфильтровать запрос на запрос, чтобы пользователи могли видеть только в том, что они могут видеть.
Установить политику разрешений
Можно использовать политику разрешений по умолчанию.DEFAULT_PERMISSION_CLASSES
настройка Глобальная настройка. Например.
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
Если не указано, этот параметр по умолчанию разрешает неограниченный доступ:
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
Вы также можете основываться наAPIView
Политика аутентификации устанавливается в представлении класса.
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
class ExampleView(APIView):
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
или на основе@api_view
Установите функцию представления декоратора.
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
@api_view(['GET'])
@permission_classes((IsAuthenticated, ))
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
Уведомление:Когда вы устанавливаете новый класс разрешений через атрибут класса или декоратор,settings.py
Настройки по умолчанию в файле игнорируются.
Справочник по API
AllowAny
AllowAny
Класс разрешений разрешает неограниченный доступ независимо от того, аутентифицирован ли запрос или нет.
Вам также не обязательно использовать это разрешение, вы можете добиться того же результата, установив пустой список или кортеж для разрешения, но вы обнаружите, что использование этого разрешения делает намерение более ясным.
IsAuthenticated
IsAuthenticated
Класс разрешений запрещает доступ любому пользователю, не прошедшему проверку подлинности.
Вы можете использовать это разрешение, если хотите, чтобы ваш API был доступен только зарегистрированным пользователям.
IsAdminUser
IsAdminUser
только разрешениеuser.is_staff
заTrue
Доступ пользователя, любому другому пользователю будет отказано.
Вы можете использовать это разрешение, если хотите, чтобы ваш API был доступен только частично доверенным администраторам.
IsAuthenticatedOrReadOnly
IsAuthenticatedOrReadOnly
Аутентифицированным пользователям разрешено выполнять любые запросы. Неавторизованные пользователи могут запрашивать только «безопасные» методы:GET
,HEAD
илиOPTIONS
.
Вы можете использовать это разрешение, если хотите, чтобы ваш API разрешал анонимным пользователям иметь разрешения на чтение и разрешал разрешения на запись только пользователям, прошедшим проверку подлинности.
DjangoModelPermissions
Этот класс разрешений соответствует стандарту Django.django.contrib.auth
Привязка разрешения модели. Это разрешение может быть использовано только с.queryset
Представление о наборе свойств. Доступ предоставляется только в том случае, если пользователь прошел проверку подлинности и ему назначены соответствующие разрешения модели.
-
POST
Запрос требует, чтобы пользователь имел на моделиadd
разрешения. -
PUT
иPATCH
Запрос требует, чтобы пользователь имел на моделиchange
разрешения. -
DELETE
Запрос требует, чтобы пользователь имел на моделиdelete
разрешения.
Поведение по умолчанию также можно переопределить для поддержки пользовательских разрешений модели. Например, вы можете включить запрос GETview
Разрешения модели.
Чтобы настроить разрешения модели, наследуйтеDjangoModelPermissions
и установить.perms_map
Атрибуты. Подробности смотрите в исходном коде.
Использование не включаетqueryset
просмотр свойств.
Если вы переопределите это разрешение с помощьюget_queryset()
Способ используется вместе с видом, вид может не иметьqueryset
Атрибуты.在这种情况下,我们建议使用 sentinel 查询集标记视图,以便此类可以确定所需的权限。 Например:
queryset = User.objects.none() # Required for DjangoModelPermissions
DjangoModelPermissionsOrAnonReadOnly
иDjangoModelPermissions
Аналогично, но также разрешает неавторизованным пользователям доступ только для чтения к API.
DjangoObjectPermissions
Этот класс разрешений привязан к стандартной структуре разрешений объектов Django, которая позволяет проверять разрешения для каждого объекта модели. Чтобы использовать этот класс разрешений, вам также необходимо добавить серверную часть разрешений, которая поддерживает разрешения на уровне объекта, например.django-guardian.
иDjangoModelPermissions
Например, это разрешение может быть применено только к тем, у кого есть.queryset
Собственность или.get_queryset()
Вид на метод. Существует только доступ к разрешениям только после того, как пользователь прошел проверку подлинности и получил соответствующие разрешения модели и соответствующие разрешения модели.
-
POST
Запрос требует, чтобы пользовательadd
разрешения. -
PUT
иPATCH
Запрос требует, чтобы пользовательchange
разрешения. -
DELETE
Запрос требует, чтобы пользовательdelete
разрешения.
Пожалуйста, обрати внимание,DjangoObjectPermissions
ненужныйdjango-guardian
пакеты, а также поддерживать другие серверные части на уровне объектов.
иDjangoModelPermissions
Мол, можно передать по наследствуDjangoObjectPermissions
и установить.perms_map
свойства для настройки разрешений модели. Подробности смотрите в исходном коде.
Уведомление: если вам нужно получитьGET
,HEAD
иOPTIONS
уровень объекта запросаview
разрешений, вам также необходимо рассмотреть возможность добавленияDjangoObjectPermissionsFilter
class, чтобы конечная точка списка возвращала только результаты, содержащие объекты, для которых у пользователя есть разрешения на просмотр.
пользовательские разрешения
Чтобы реализовать настраиваемые разрешения, наследуйтеBasePermission
и реализовать один или оба из следующих методов:
.has_permission(self, request, view)
.has_object_permission(self, request, view, obj)
Если запросу предоставлен доступ, метод должен вернутьTrue
, иначе возвратFalse
.
Если вам нужно проверить, является ли запрос чтением или записью, вы должныSAFE_METHODS
проверить метод запроса,SAFE_METHODS
содержит'GET'
,'OPTIONS'
и'HEAD'
кортеж из . Например:
if request.method in permissions.SAFE_METHODS:
# Check permissions for read-only request
else:
# Check permissions for write request
Note: только на уровне просмотраhas_permission
Вызов на уровне экземпляра выполняется только после прохождения проверки.has_object_permission
метод. Также обратите внимание, что для запуска проверок на уровне экземпляра код представления должен явно вызывать.check_object_permissions(request, obj)
. Если вы используете общий вид, он будет использоваться по умолчанию. (Функция просмотра, основанная на необходимости явной проверки прав доступа к объекту, срабатывающая при сбоеPermissionDenied
. )
Если тест не пройден, пользовательское разрешение выдастPermissionDenied
аномальный. Чтобы изменить сообщения об ошибках, связанных с исключениями, внедрите их непосредственно в собственное разрешение.message
Атрибуты. В противном случае будет использоватьсяPermissionDenied
изdefault_detail
Атрибуты.
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'Adding customers not allowed.'
def has_permission(self, request, view):
...
взять каштан
Ниже приведен пример класса разрешений входящих запросов Copylist IP-адреса для сравнения, и запрос отклонен в черный список IP.
from rest_framework import permissions
class BlacklistPermission(permissions.BasePermission):
"""
Global permission check for blacklisted IPs.
"""
def has_permission(self, request, view):
ip_addr = request.META['REMOTE_ADDR']
blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()
return not blacklisted
В дополнение к глобальным разрешениям, которые выполняются для всех входящих запросов, также можно создавать разрешения на уровне объекта, которые выполняются только для операций, влияющих на определенные экземпляры объекта. Например:
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
# Instance must have an attribute named `owner`.
return obj.owner == request.user
Обратите внимание, что общие представления будут проверять наличие соответствующих разрешений на уровне объекта, но если вы пишете свои собственные настраиваемые представления, вам необходимо убедиться, что вы проверили свои собственные разрешения на уровне объекта. Вы можете сделать это, позвонив из представления после того, как у вас есть экземпляр объектаself.check_object_permissions(request, obj)
для завершения этой операции. Если какие-либо проверки разрешений на уровне объекта завершатся неудачей, этот вызов вызовет соответствующийAPIException
, иначе он просто вернется.
Также обратите внимание, что общие представления будут проверять разрешения на уровне объекта только для представлений одного экземпляра модели. Если вам нужна фильтрация представления списка на уровне объекта, вам нужно отдельно отфильтровать набор запросов.