Pular para o conteúdo
Código e Café com PauloDev: Explorando o Universo da Programação

Código e Café com PauloDev: Explorando o Universo da Programação

Explore o universo da programação e tecnologia com PauloDev. Descubra insights, tutoriais e inovações que moldam o futuro digital. De linhas de código a ideias revolucionárias, embarque nesta jornada tech onde a paixão pela inovação se encontra com a expertise do desenvolvimento. Seja bem-vindo ao blog que transforma códigos em narrativas de vanguarda, guiado pela visão única de PauloDev no vasto panorama tecnológico.

  • Meu portifolio

Python para o desenvolvimento Web: Como o Django pode alavancar na escrita do seu código

3 de março de 2025
Por Paulo In Django, Python

Python para o desenvolvimento Web: Como o Django pode alavancar na escrita do seu código

Uma das coisas mais interessantes de usar python para o desenvolvimento, é a facilidade que ele nos traz nas tarefas comuns no dia a dia. Um ótimo exemplo é o Django, um framework python que nos auxilia na criação de soluções web, sejam elas REST APIs ou até mesmo um monolito com as views todas no mesmo projeto.

Trazendo o exemplo do Django, e para mostrar como ele pode alavancar a sua produção no dia a dia de desenvolvimento, hoje quero mostrar para você como configurar uma autenticação via token JWT utilizando o framework.

Conhecendo o JWT

Antes de te mostrar o código, é importante que você saiba o que é um token JWT. O JSON Web Token (JWT) é um padrão aberto (RFC 7519) para criação de tokens compactos e seguros, que podem ser utilizados para autenticação e/ou troca de informações entre partes confiáveis. Ele é amplamente utilizado em sistema distribuídos, autenticação de APIs e Single Sign-On (SSO).

O JWT é composto por três partes codificadas em Base64URL, separadas por pontos (.):

  1. Header (Cabeçalho): Define o tipo do token (typ: “JWT”) e o algoritmo de assinatura (alg: “HS256”, por exemplo)
  2. Payload (Corpo): Contém as declarações (claims) do token, que podem ser padrão (como sub, iat, exp) ou personalizadas
  3. Signature (Assinatura): É gerada combinando o Header e o Payload com uma chave secreta (no caso de HMAC) ou uma chave privada (no caso de RSA ou ECDSA)

Um JWT antes da codificação teria essa cara:

{
  "alg": "HS256",
  "typ": "JWT"
}
.
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1710451200,
  "exp": 1710454800
}

E ao ser gerado, seria bem parecido com isso:

eyJjbGllbnRfaWQiOiJZekV6TUdkb01ISm5PSEJpT0cxaWJEaHlOVEE9IiwicmVzcG9uc2Vf
dHlwZSI6ImNvZGUiLCJzY29wZSI6ImludHJvc2NwZWN0X3Rva2VucywgcmV2b2tlX3Rva2VucyIsImlzcyI6ImJqaElSak0xY1hwYWEyMXpkV3RJU25wNmVqbE1iazQ0YlRsTlpqazNkWEU9Iiwic3ViIjoiWXpFek1HZG9NSEpuT0hCaU9HMWliRGh5TlRBPSIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0Ojg0NDMve3RpZH0ve2FpZH0vb2F1dGgyL2F1dGhvcml6ZSIsImp0aSI6IjE1MTYyMzkwMjIiLCJleHAiOiIyMDIxLTA1LTE3VDA3OjA5OjQ4LjAwMCswNTQ1In0

Exemplo prático com DJango

Agora que você já conhece um pouco sobre o JWT, vamos começar o nosso exemplo prático, primeiro vamos iniciar nosso projeto Django. Recomendo que utilize um ambiente virtual python (pyenv) para seguir o tutorial, apenas para isolar as dependências do projeto, mas caso queira seguir apenas com o python da sua máquina não tem problema.

Vamos começar instalando as dependências do Django:

pip install django djangorestframework markdown django-filter

Agora, as dependências para gerar os Tokens JWT:

pip install djangorestframework-simplejwt

Por fim, vamos criar nosso projeto Django:

django-admin startproject exemplotokens
cd exemplotokens

E agora, criar o app que vai servir como base para o sistema:

django-admin startapp geradordetokens

Pronto, seu projeto Django já está pronto. Agora vamos configurar para que ele seja interpretado como uma Api REST e fazer as primeiras configurações do JWT. Dentro do settings.py do projeto, devemos adicionar as seguintes configuranções:

INSTALLED_APPS = [
   ...
   'rest_framework',
   'geradordetokens',
   'rest_framework.authtoken',
]

A configuração acima adiciona o rest_framework ao nosso projeto, além do nosso app geradordetokens e a biblioteca responsável por fazer a autenticação por token (rest_framework.authtoken)

Agora, devemos configurar o JWT como o meio padrão de autenticação do nosso projeto, para isso, dentro do settings.py adicionamos:

\REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': [
       'rest_framework_simplejwt.authentication.JWTAuthentication',
   ]
}

E agora, adicionamos algumas configurações de como o nosso token irá ser gerado:

from datetime import timedelta


SIMPLE_JWT = {
   'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
   'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
   'ROTATE_REFRESH_TOKENS': False,
   'BLACKLIST_AFTER_ROTATION': True,
   'ALGORITHM': 'HS256',
}

Essas são as configurações padrões, que define o vencimento do token em 60min e do refresh token em 1 dia. Além de definir o algoritmo padrão como o HS256, mas você pode ver mais configurações na documentação oficial da biblioteca:

https://django-rest-framework-simplejwt.readthedocs.io/en/latest

Configurando as views

Com as settings configuradas, podemos seguir com as configurações dos nossos endpoints de autenticação e cadastro de usuários. Primeiro, vamos criar os serializers responsáveis para cada endpoint. Caso você não saiba, os serializers são os atores responsáveis por interpretar um JSON para o código Python, e também, passar um código Python para JSON. Dentro de geradordetokens, vamos criar um arquivo serializers.py e adicionar o seguinte:

from rest_framework import serializers
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError


class LoginSerializer(serializers.Serializer):
   email = serializers.EmailField()
   password = serializers.CharField(write_only=True)




class UserRegisterSerializer(serializers.ModelSerializer):
   password = serializers.CharField(write_only=True)
  
   class Meta:
       model = User
       fields = ['email', 'password', 'username']
  
   def create(self, validated_data):
       user = User.objects.create_user(
           email=validated_data['email'],
           password=validated_data['password'],
           username=validated_data['username']
       )
       return user
  
   def validate_email(self, value):
       user = User.objects.filter(email=value).first()
       if user:
           raise ValidationError('Este e-mail já está em uso!')
       return value


Agora, por questões de boas práticas, vamos criar um novo arquivo services/authentication.py para isolar a nossa lógica de autenticação. Dentro dele vamos adicionar:

from rest_framework.response import Response
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken


class Authenticator():
   def authenticate(self, serializer):      
       if serializer.is_valid():
           email = serializer.validated_data['email']
           password = serializer.validated_data['password']


           try:
               user = User.objects.get(email=email)
           except User.DoesNotExist:
               return Response({"error": "E-mail ou senha inválidos"}, status=400)
          
           if not user.check_password(password):
               return Response({"error": "E-mail ou senha inválidos"}, status=400)


           refresh = RefreshToken.for_user(user)
           access_token = str(refresh.access_token)
          
           return Response({
               "access_token": access_token,
               "refresh_token": str(refresh),
           })


       return Response({"error": "E-mail ou senha inválidos"}, status=400)

Aqui, estou apenas verificando o e-mail e a senha do nosso usuário, e caso esteja tudo certo, gero o token de acesso e o refresh token.

Agora sim, podemos gerar nossas views para os endpoints da nossa aplicação. Dentro de views.py adicionamos o seguinte:

from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response
from .serializers import LoginSerializer, UserRegisterSerializer
from .services.authentication import Authenticator


class LoginView(APIView):
   def post(self, request):
       serializer = LoginSerializer(data=request.data)
       auth = Authenticator()
       return auth.authenticate(serializer)
  
class RegisterView(APIView):
   def post(self, request):
       serializer = UserRegisterSerializer(data=request.data)
      
       if serializer.is_valid():
           serializer.save()
           return Response({"message": "Usuário cadastrado com sucesso!"}, status=status.HTTP_201_CREATED)
      
       return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Nada muito complicado, o LoginView será o responsável pela autenticação dos nossos usuários. Enquanto o RegisterView, ficará responsável pelo cadastro de novos usuários. Agora, para que isso funcione, vamos cadastrar os endpoints, então dentro de geradordetokens vamos criar o arquivo urls.py e adicionar o seguinte código:

from django.urls import path
from .views import LoginView, RegisterView


urlpatterns = [
   path('auth/login/', LoginView.as_view(), name='login'),
   path('auth/register/', RegisterView.as_view(), name='register'),
]

Por fim, dentro do urls.py global da nossa aplicação, que fica em exemplotokens/ vamos importar essas configurações:

from django.urls import path, include


urlpatterns = [
   path('api/v1/', include('geradordetokens.urls'))
]

E pronto, nossa autenticação via tokens JWT está pronta, além do cadastro de novos usuários.

Testando nosso código:

Agora que temos tudo pronto, vamos testar o que acabamos de fazer. Para os testes, estarei utilizando o postman, mas com os exemplos que deixarei abaixo, você pode facilmente executar pelo terminal do seu sistema operacional usando o CURL. O Postman é apenas para uma melhor visualização.

Antes de rodar o projeto, vamos rodar as migrations do Django, para que as tabelas padrões de usuário sejam criadas:

python manage.py migrate

Caso você não tenha configurado outro banco, um arquivo .sqlite3 será criado dentro dos diretórios do seu projeto, ele será o nosso banco de teste. Caso queira usar outro, não tem problema, irá funcionar na mesma forma.

Agora sim, podemos rodar o nosso projeto:

python manage.py runserver

Primeiro, vamos cadastrar um novo usuário no sistema:

curl --location 'http://127.0.0.1:8000/api/v1/auth/register/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "Usuario",
    "email": "email@email.com",
    "password": "12345678"
}'

A resposta deve ser uma mensagem de sucesso. Caso tenha algum erro, volte no tutorial e seguida cada passo novamente. Agora, vamos fazer o login:

curl --location 'http://127.0.0.1:8000/api/v1/auth/login/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "email@email.com",
    "password": "12345678"
}'

Como resultado, você deve receber o access_token e o refresh_token:

{
   "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQxMDEwMjk5LCJpYXQiOjE3NDEwMDY2OTksImp0aSI6ImFjMmYyNzhiMjRiMDQzY2ZhMzc1NmMwZGYzYTU1ZGI1IiwidXNlcl9pZCI6MX0.kAu-Nxuv-KZzr5PMp9sO62iCOjFy3lJYlpdLVyy-Ods",
   "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTc0MTA5MzA5OSwiaWF0IjoxNzQxMDA2Njk5LCJqdGkiOiI4ZDg2NjIyYzc1MTA0ZjdkOTg2YzJkZTBkMmNmMzQwOCIsInVzZXJfaWQiOjF9.ACiG3itxjgTBaIsj-ldNDJR0I2V1YB4OT4y0SUP0pNk"
}

Pronto, já estamos recebendo nossas credenciais de acesso. Para testar se elas estão passando, vamos adicionar um novo endpoint que solicita o token para ser acessado. Então, dentro das views.py do nosso projeto, vamos utilizar o IsAuthenticated do Django, que é responsável por solicitar credenciais de acesso para que uma rota funcione.

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
class ClassParaAutenticar(APIView):
   permission_classes = [IsAuthenticated]
   def get(self, request):
       return Response({"message": "Estou autenticado"})


Por fim, vamos adicionar ele no nosso urls.py

from django.urls import path
from .views import LoginView, RegisterView, ClassParaAutenticar


urlpatterns = [
   path('auth/login/', LoginView.as_view(), name='login'),
   path('auth/register/', RegisterView.as_view(), name='register'),
   path('autenticado/', ClassParaAutenticar.as_view(), name='rota_autenticada')
]

Agora, se tentarmos acessar esse endpoint sem o token, iremos receber uma mensagem falando sobre o uso obrigatório do token:

curl --location 'http://127.0.0.1:8000/api/v1/autenticado/'


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

Passando o token, nosso acesso será liberado:

curl --location 'http://127.0.0.1:8000/api/v1/autenticado/' \
--header 'Authorization: Bearer <seu_token_vem_aqui>'


Response:
{
   "message": "Estou autenticado"
}

Conclusão

Nesse tutorial você acaba de ver como é simples a criação de tokens JWT em uma aplicação Django, apesar de longo, esse artigo busca ser o mais explicativo o possível para que você consiga fazer as suas próprias configurações.

Promoção
Written by:

Paulo

Ver todos os posts

Categorias

  • Android
  • Android Studio
  • Angular
  • API
  • AWS
  • Back-end
  • Bash
  • Boas Práticas
  • CSharp
  • CSS
  • Django
  • Docker
  • Electron
  • Front-end
  • Git
  • Github
  • Html
  • Http
  • Java
  • JavaScript
  • Laravel
  • Linha de comando
  • Linux
  • Machine Learning
  • Metodologias
  • Mysql
  • Node
  • NoSql
  • PHP
  • Power Shell
  • Python
  • Segurança
  • Sem categoria
  • SQL
  • Tecnologia
  • Testes
  • VueJs
  • Windows

Últimos posts

  • Python para o desenvolvimento Web: Como o Django pode alavancar na escrita do seu código
  • Conheça as Transactions e como elas podem te ajudar a testar o seu sistema
  • Melhorando a performance dos seus projetos PHP, conheça o OPCache e o JIT
  • Redis com Laravel: Uma ferramenta poderosa para o escalonamento horizontal da sua aplicação
  • Conhecendo e configurando um servidor de Load Balance com YARP e NGINX

© Todos os direitos reservados PauloDev 2023