Tutorial Django Experience 2022
Doc: https://www.django-rest-framework.org/api-guide/permissions/
Se você define em settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
você não precisa declarar em todas as Viewsets, por isso fica global.
Se você não definir o padrão é:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
Onde o acesso é liberado para tudo, mas você não precisa definir isso, pois é o default do Django.
Se você não estiver autenticado, você só poderá ler, acessar o GET
. Caso esteja autenticado, então os outros métodos serão liberados. Exemplo, você pode ver os movies
, mas não pode editar.
Exemplo
# movie/api/viewsets.py
from rest_framework.permissions import IsAuthenticatedOrReadOnly
class MovieViewSet(viewsets.ModelViewSet):
...
permission_classes = (IsAuthenticatedOrReadOnly,)
Entre no Postman, e faça um GET sem autenticação em http://localhost:8000/api/v1/movies/
Depois faça um POST sem autenticação em http://localhost:8000/api/v1/movies/
{
"title": "Inception",
"rating": 5,
"like": true
}
Depois tente com autenticação.
É chamado, por exemplo, quando é executada uma instância do model.
As permissões rodam quando .get_object()
é chamado.
Acesso liberado para todos.
Exige que o usuário esteja autenticado.
Somente usuários do tipo user.is_staff
igual a True
podem acessar.
Qualquer um pode acessar o método GET
, os demais métodos exige autenticação.
São as permissões em nível de model, definidas pelo Django Admin.
Método | Permissão |
---|---|
GET | view |
POST | add |
PUT | change |
DELETE | delete |
Exemplo
Vamos criar um grupo chamado Editor. Significa que o usuário que for Editor poderá editar o filme, caso contrário só podem ler.
user.is_superuser = False
.movie | Can change movie
a este grupo.# movie/api/viewsets.py
class MovieViewSet(viewsets.ModelViewSet):
...
permission_classes = (DjangoModelPermissions,)
Tente fazer o PUT
com um usuário fora do grupo.
Depois tente com um usuário do grupo.
Exemplo
Vamos criar um grupo chamado Criador. Ele poderá criar ou editar.
movie | Can add movie
a este grupo.movie | Can change movie
a este grupo.Tente fazer o POST
com um usuário fora do grupo.
Depois tente com um usuário do grupo.
Depois faça o mesmo com PUT
.
Vamos considerar que se um usuário for do perfil Infantil e a censura do filme for 14 anos, então ele não poderá ver os detalhes do filme.
#movie/viewsets.py
class CensurePermission(BasePermission):
age_user = 14
group_name = 'Infantil'
message = 'Este filme não é permitido para este perfil.'
def has_object_permission(self, request, view, obj):
# Retorna uma lista de todos os grupos do usuário logado.
groups = request.user.groups.values_list('name', flat=True)
censure = obj.censure
if self.group_name in groups and censure >= self.age_user:
response = {
'message': self.message,
'status_code': status.HTTP_403_FORBIDDEN
}
raise DRFValidationError(response)
else:
return True
class MovieViewSet(viewsets.ModelViewSet):
...
permission_classes = (DjangoModelPermissions, CensurePermission)
Tente acessar um filme com censura de 14 anos e um de 13, no perfil “Infantil”.
#movie/viewsets.py
class NotDeletePermission(BasePermission):
message = 'Nenhum registro pode ser deletado.'
def has_permission(self, request, view):
if request.method == 'DELETE':
response = {
'message': self.message,
'status_code': status.HTTP_403_FORBIDDEN
}
raise DRFValidationError(response)
else:
return True
class MovieViewSet(viewsets.ModelViewSet):
...
permission_classes = (DjangoModelPermissions, CensurePermission, NotDeletePermission)