O guia definitivo de segurança em aplicações Django Rest Framework: Autenticação e autorização
Introdução
Garantir a segurança de aplicações é essencial no desenvolvimento de sistemas reais. Portanto, abordaremos uma forma de garantir eficiência e segurança em aplicações Django/DRF. Utilizaremos o esquema de autenticação baseada em tokens, especificamente o JWT (JSON Web Token). No campo da segurança de software, duas palavras são amplamente discutidas: autenticação e autorização. Autenticação refere-se ao ato de validar as credenciais do usuário, enquanto autorização refere-se às permissões do usuário no projeto.
Neste artigo, usaremos o esquema de autenticação baseada em tokens com JWT (JSON Web Token) como forma de emissão de tokens. O JWT é um padrão amplamente utilizado para trafegar JSON entre diferentes aplicações (back-end e front-end).
Para contextualizar nossa abordagem, desenvolveremos uma aplicação simples no domínio de um blog, centrada na entidade 'artigo'. A regra para os endpoints relacionados aos artigos é que apenas usuários autenticados têm permissão para criar, deletar ou atualizar artigos. Usuários não autenticados têm autorização apenas para visualizar os artigos, sem capacidade de modificar ou excluir qualquer conteúdo. Para lidar com a autorização, faremos uso de um recurso nativo do Django Rest Framework: as permissões.
Criar o projeto Django
É uma boa prática sempre usar um ambiente virtual (uma forma de isolar todas as configurações do nosso ambiente Python em termos de dependência do projeto Django e do sistema operacional) para iniciar o nosso app Django. Como ferramenta de ambiente virtual, usaremos o virtualenv
.
Crie uma pasta para armazenar o seu projeto Django:
mkdir auth-django-rest-framework
Crie o ambiente virtual e ative-o:
virtualenv venv source
venv/bin/activate # Linux
Com o ambiente virtual já instalado e ativado, instale o Django:
pip install django
Crie o projeto Django:
django-admin startproject config .
OBS: Gosto de dar o nomeconfig
para o meu projeto no momento da criação porque, ao executarmosdjango-admin startproject
, o Django cria apenas a estrutura inicial do nosso app.
Crie um app inicial:
Este app será usado como modelo para adicionar nossos endpoints gerais da aplicação e o model de Artigo, conforme mencionado anteriormente.
django-admin startapp core
Como ficou a estrutura do nosso projeto
Configurar o Django Rest Framework
Instale a dependência:
pip install djangorestframework
Adicione rest_framework
no arquivo de configuração do Django (config/settings.py
):
INSTALLED_APPS = [
...
'rest_framework',
]
Instalar a biblioteca para trabalhar com Autenticação
O próprio Django Rest Framework já nos provê mecanismos de autenticação para nossa API REST, como o Basic Authentication ou Token Based Authentication (token permanente). No entanto, nossa intenção aqui é obter mais segurança através do uso de tokens com tempo de expiração.
Para isso, usaremos a biblioteca drf-simplejwt
.
Instale essa biblioteca:
pip install djangorestframework-simplejwt
Adicione rest_framework_simplejwt
ao INSTALLED_APPS
no arquivo config/settings.py
do seu projeto:
INSTALLED_APPS = [
...
'rest_framework_simplejwt',
]
Após a instalação das dependências necessárias, precisamos configurar o objeto de configuração do Django Rest Framework para obter todos os benefícios que esse framework nos oferece.
Com o pacote rest_framework_simplejwt
instalado, podemos definir os endpoints que os usuários utilizarão para se autenticar e atualizar tokens.
Configuração no settings.py
:
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
}
Configuração das URLs para autenticação e atualização de tokens:
No seu arquivo urls.py
, adicione os endpoints para autenticação e atualização de tokens:
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
path("admin/", admin.site.urls),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
Essa configuração habilita o Django Rest Framework a trabalhar com o sistema de autenticação da biblioteca que instalamos (simplejwt). O valor que adicionamos na propriedade DEFAULT_PERMISSION_CLASSES
informa que, por padrão, todos os endpoints da nossa API são acessíveis somente para usuários autenticados. Isso já está relacionado à autorização, porém ainda podemos aplicar autorização a nível de endpoints, que é o que faremos a seguir.
Após todas as etapas de configuração do sistema de autenticação serem finalizadas, vamos criar endpoints para expor os recursos relacionados à entidade Artigo que criamos. Como é padrão no Django Rest Framework, vamos criar os serializers, viewsets e definir a rota do nosso recurso de artigo.
Criar Model, Serializers, Viewsets e Rotas
Criar o modelo de artigo
from django.db import models
class Artiche(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
Criar o Serializer:
No arquivo core/serializers.py
, crie um serializer para a entidade Artigo:
from rest_framework.serializers import ModelSerializer
from core.models import Artiche
class ArticheModelSerializer(ModelSerializer):
class Meta:
model = Artiche
fields = ("id", "title", "content")
Criar o Viewset:
No arquivo core/views.py
, crie um viewset para a entidade Artigo:
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.viewsets import ModelViewSet
from core.api.serializers import ArticheModelSerializer
from core.models import Artiche
class ArticheModelViewSet(ModelViewSet):
queryset = Artiche.objects.all()
serializer_class = ArticheModelSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
Definir as Rotas da api:
No arquivo config/api_router.py
, defina as rotas para o viewset de Artigo:
from rest_framework.routers import DefaultRouter
from core.api.viewsets import ArticheModelViewSet
router = DefaultRouter()
router.register(r"artiche", ArticheModelViewSet)
urlpatterns = router.urls
Incluir as Rotas no URLconf Principal:
No arquivo config/urls.py
, inclua as rotas da api:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('config.api_router')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
Com essas etapas concluídas, você terá configurado a autenticação JWT e criado endpoints com autorização/permissões para o recurso de Artigo no Django Rest Framework, garantindo que apenas usuários autenticados possam acessar esses endpoints em operações especificas.
Os retângulos vermelhos na imagem acima mostram os novos arquivos que foram adicionados.
Após a configuração completa do nosso app, testamos nossa aplicação utilizando o Insomnia. Inicialmente, verificamos a funcionalidade do endpoint de token e, em seguida, exploramos o endpoint de artigos para validar as permissões configuradas.
Teste do endpoint de autenticação
Teste para validar que para usuários não autenticado, não deve permite a criação de novos artigos.
Teste para validar que para usuários autenticados, o acesso a efetuar a criação é concebido
Teste para usuários não autenticados, conseguem visualizar a lista de artigos e obter detalhes
Para ver todos os detalhes da aplicação, deixo o link do meu repositório com o projeto finalizado.