DEV Community

Gabriel Villacis
Gabriel Villacis

Posted on

Gestor de Iniciativas Ecológicas: Django Rest Framework (Parte 5)

Tutorial 5: Implementación de API de Comentarios con Autenticación JWT y Configuración de Tiempos de Vida de Tokens en Django Rest Framework

Objetivo: En este tutorial, aprenderás a implementar un sistema de comentarios en el proyecto Iniciativas Ecológicas utilizando Django Rest Framework (DRF) con autenticación basada en JWT (JSON Web Tokens). Además, configuraremos los tiempos de vida de los tokens de acceso y refresh. También aprenderás a probar los endpoints de la API usando Postman.


Paso 1: Configuración Inicial de Django Rest Framework y JWT

Lo primero que haremos es configurar Django Rest Framework (DRF) y agregar soporte para la autenticación basada en tokens JWT.

  1. Instalar Django Rest Framework y JWT:

Ejecute el siguiente comando para instalar DRF y djangorestframework-simplejwt, que proporciona soporte para JWT:

   poetry add djangorestframework djangorestframework-simplejwt
Enter fullscreen mode Exit fullscreen mode
  1. Agregar Django Rest Framework a las aplicaciones instaladas:

Abre el archivo settings.py y añade 'rest_framework' a la lista de aplicaciones instaladas:

   INSTALLED_APPS = [
       ...
       'rest_framework',
   ]
Enter fullscreen mode Exit fullscreen mode
  1. Configurar JWT y los tiempos de vida de los tokens en settings.py:

Para la autenticación JWT, configuraremos los tiempos de vida tanto para el access token como para el refresh token. En este caso, vamos a establecer que el access token tenga un tiempo de vida de 15 minutos, mientras que el refresh token durará 7 días.

Agrega lo siguiente en settings.py:

   from datetime import timedelta

   REST_FRAMEWORK = {
       'DEFAULT_AUTHENTICATION_CLASSES': [
           'rest_framework_simplejwt.authentication.JWTAuthentication',
       ],
       'DEFAULT_PERMISSION_CLASSES': [
           'rest_framework.permissions.IsAuthenticated',
       ],
   }

   SIMPLE_JWT = {
       'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),  # Tiempo de vida del access token
       'REFRESH_TOKEN_LIFETIME': timedelta(days=7),  # Tiempo de vida del refresh token
       'ROTATE_REFRESH_TOKENS': True,  # Renueva el refresh token al usarlo
   }
Enter fullscreen mode Exit fullscreen mode
  • ACCESS_TOKEN_LIFETIME: El access token expirará en 15 minutos.
  • REFRESH_TOKEN_LIFETIME: El refresh token será válido por 7 días.
  • ROTATE_REFRESH_TOKENS: Al refrescar el token de acceso, el refresh token también se renovará automáticamente.

Paso 2: Crear el Modelo de Comentario

A continuación, definiremos el modelo para los comentarios, que estará relacionado con las iniciativas y los usuarios.

  1. Definir el modelo Comentario en models.py dentro de la app iniciativas:
   from django.contrib.auth.models import User

   class Comentario(models.Model):
       iniciativa = models.ForeignKey(Iniciativa, related_name="comentarios", on_delete=models.CASCADE)
       usuario = models.ForeignKey(User, on_delete=models.CASCADE)
       comentario = models.TextField()
       fecha_creacion = models.DateTimeField(auto_now_add=True)

       def __str__(self):
           return f"Comentario de {self.usuario.username} en {self.iniciativa.nombre}"
Enter fullscreen mode Exit fullscreen mode
  • iniciativa: Relaciona el comentario con una iniciativa.
  • usuario: El autor del comentario.
  • comentario: El contenido del comentario.
  • fecha_creacion: La fecha en que fue creado el comentario.
  1. Aplicar migraciones:

Después de definir el modelo, debemos crear las tablas en la base de datos:

   poetry run python manage.py makemigrations
   poetry run python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

Paso 3: Crear el Serializer para Comentarios

Los serializadores permiten convertir los datos de Django en formato JSON y viceversa. Vamos a crear un serializador personalizado para los comentarios.

  1. Definir el ComentarioSerializer en serializers.py dentro de la app iniciativas:
   from rest_framework import serializers
   from .models import Comentario

   class ComentarioSerializer(serializers.ModelSerializer):
       usuario = serializers.StringRelatedField(read_only=True)  # Mostrar el nombre del usuariousuario
       iniciativa = serializers.PrimaryKeyRelatedField(queryset=Iniciativa.objects.all())  # Aceptar el ID de la iniciativa

       class Meta:
           model = Comentario
           fields = ['id', 'usuario', 'iniciativa', 'comentario', 'fecha_creacion']

       # Validar el campo comentario
       def validate_comentario(self, value):
           if len(value) < 10:
               raise serializers.ValidationError("El comentario debe tener al menos 10 caracteres.")
           return value
Enter fullscreen mode Exit fullscreen mode
  • Añadimos una validación para el campo comentario para asegurarnos de que tenga al menos 10 caracteres.

Paso 4: Crear el ViewSet para los Comentarios

Crearemos un ViewSet para gestionar las operaciones CRUD en los comentarios y personalizaremos los métodos list, create, retrieve, update, y destroy.

  1. Definir el ComentarioViewSet en viewsets.py:
   from rest_framework import viewsets, status
   from .models import Comentario
   from .serializers import ComentarioSerializer
   from rest_framework.permissions import IsAuthenticatedOrReadOnly
   from rest_framework.response import Response

   class ComentarioViewSet(viewsets.ModelViewSet):
       queryset = Comentario.objects.all()
       serializer_class = ComentarioSerializer
       permission_classes = [IsAuthenticatedOrReadOnly]

       # Personalizar el método create: asignar automáticamente el usuario
       def create(self, request, *args, **kwargs):
           serializer = self.get_serializer(data=request.data)
           if serializer.is_valid():
               serializer.save(usuario=request.user)
               return Response(serializer.data, status=status.HTTP_201_CREATED)
           return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

       # Personalizar el método update: actualizar un comentario solo si es del usuario
       def update(self, request, *args, **kwargs):
           instance = self.get_object()
           if instance.usuario != request.user:
               return Response({'error': 'No tienes permiso para actualizar este comentario.'}, status=status.HTTP_403_FORBIDDEN)
           serializer = self.get_serializer(instance, data=request.data)
           if serializer.is_valid():
               serializer.save()
               return Response(serializer.data)
           return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

       # Personalizar el método destroy: eliminar un comentario solo si es del usuario
       def destroy(self, request, *args, **kwargs):
           instance = self.get_object()
           if instance.usuario != request.user:
               return Response({'error': 'No tienes permiso para eliminar este comentario.'}, status=status.HTTP_403_FORBIDDEN)
           instance.delete()
           return Response(status=status.HTTP_204_NO_CONTENT)
Enter fullscreen mode Exit fullscreen mode
  • create: Asigna el usuario autenticado al crear un comentario.
  • update: Permite actualizar solo los comentarios creados por el usuario autenticado.
  • destroy: Permite eliminar solo los comentarios creados por el usuario autenticado.

Paso 5: Configurar las Rutas de la API

Para que la API esté accesible, necesitamos registrar las rutas correspondientes.

  1. Registrar las rutas en urls.py del proyecto principal:

Vamos a registrar las rutas de la API y también las rutas necesarias para la autenticación JWT.

En el archivo urls.py del proyecto principal, agrega lo siguiente:

   from rest_framework.routers import DefaultRouter
   from iniciativas.viewsets import ComentarioViewSet
   from rest_framework_simplejwt.views import (
       TokenObtainPairView,
       TokenRefreshView,
   )

   router = DefaultRouter()
   router.register(r'api/comentarios', ComentarioViewSet, basename='comentarios')

   urlpatterns = [
       # Rutas de la API
       path('', include(router.urls)),

       # Rutas para autenticación JWT
       path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
       path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
   ]
Enter fullscreen mode Exit fullscreen mode
  • TokenObtainPairView: Genera el token de acceso y el token de refresh.
  • TokenRefreshView: Permite refrescar el token de acceso usando el

token de refresh.


Paso 6: Probar la API con Postman

Ahora probaremos los endpoints de la API utilizando Postman.

  1. Obtener el Token de Acceso:
  • Envía una solicitud POST a http://127.0.0.1:8000/api/token/ con el siguiente cuerpo en formato JSON:

     {
         "username": "tu_usuario",
         "password": "tu_contraseña"
     }
    
  • La respuesta será un par de tokens access y refresh. Copia el token access.

  1. Probar los Endpoints Protegidos:
  • Para acceder a los comentarios o crear uno nuevo, debes enviar el token access en el encabezado de la solicitud con el formato:

     Authorization: Bearer <tu_access_token>
    
  • Ejemplo para listar los comentarios:

    • Método: GET
    • URL: http://127.0.0.1:8000/api/comentarios/
    • Encabezado: Authorization: Bearer <access_token>
  • Ejemplo para crear un comentario:

    • Método: POST
    • URL: http://127.0.0.1:8000/api/comentarios/
    • Encabezado: Authorization: Bearer <access_token>
    • Cuerpo:
     {
         "iniciativa": 1,
         "comentario": "Este es un comentario de prueba"
     }
    
  1. Refrescar el Token:
  • Envía una solicitud POST a http://127.0.0.1:8000/api/token/refresh/ con el siguiente cuerpo:

     {
         "refresh": "tu_refresh_token"
     }
    
  • Esto te devolverá un nuevo token de acceso.


Conclusión

En este tutorial, hemos creado un sistema de comentarios con Django Rest Framework y protegimos los endpoints con autenticación basada en JWT. Personalizamos los métodos list, create, retrieve, update, y destroy dentro de un ViewSet, configuramos los tiempos de vida de los tokens JWT, y configuramos las rutas necesarias para la autenticación. Finalmente, aprendiste a probar los endpoints utilizando Postman.

Top comments (0)