Asegura tus endpoints en Django Rest Framework con un flujo claro de autenticación, autorización y permission classes. Con SessionAuthentication, inicio de sesión vía API auth y permisos como IsAuthenticated, IsAuthenticatedOrReadOnly y un permiso personalizado IsDoctor, puedes controlar quién entra y qué puede hacer en tu API.
¿Qué significan autenticación y autorización en APIs?
La autenticación verifica quién eres: como mostrar tu documento al llegar a un hotel. En sistemas, suele ser usuario y contraseña. La autorización define qué puedes hacer: la llave del hotel abre solo tu habitación, no todas. En APIs, es el conjunto de permisos que habilitan acciones específicas.
Autenticación: demostrar identidad con credenciales.
Autorización: limitar acciones según permisos.
Metáfora del hotel aplicada a endpoints.
¿Cómo configurar Django Rest Framework con session authentication?
Django Rest Framework reutiliza el sistema de Django. Con SessionAuthentication, tras autenticarse, Django agrega una cookie que viaja en cada request para identificarte. Así, puedes usar el mismo login que en Django admin.
Configura DEFAULT_AUTHENTICATION_CLASSES con SessionAuthentication.
Agrega la URL de API auth e incluye las rutas del sistema de DRF.
Recarga la interfaz de DRF: aparece el link Login.
Crea un superusuario con manage.py create super user.
Inicia sesión y verás tu usuario y el Logout en la esquina superior derecha.
# urls.py (agregar la ruta de autenticación de DRF)urlpatterns =[# ... path('api-auth/', include('rest_framework.urls')),]
# crear superusuariopython manage.py create super user
¿Cómo aplicar permisos y proteger endpoints con Django Rest?
Con permission classes puedes exigir autenticación, permitir solo lectura a anónimos o crear reglas a la medida. La interfaz de DRF reacciona a estos permisos: si no puedes escribir, oculta formularios.
¿Qué permission classes usar para acceso seguro?
Al definir en tu view set algo como permission_classes, puedes activar IsAuthenticated para que todo el view set funcione solo si hay sesión iniciada.
Si no hay sesión, devuelve un detalle en JSON: “La autenticación no está proveída”.
La respuesta es un 401 al estar deslogueado.
Al loguearte, los endpoints vuelven a responder.
# ejemplo en un ViewSetclassDoctorViewSet(ModelViewSet): permission_classes =[IsAuthenticated]
¿Cómo permitir lectura pública con IsAuthenticatedOrReadOnly?
Cuando necesitas listar recursos públicamente pero evitar modificaciones a usuarios anónimos, usa IsAuthenticatedOrReadOnly.
Usuarios anónimos ven la lista.
La UI de DRF oculta el formulario de edición.
Usuarios autenticados mantienen las acciones de escritura.
Autenticación: DRF soporta varios métodos de autenticación (Basic, Session, Token, JWT) y puedes configurarlos según las necesidades de tu proyecto.
Permisos: DRF proporciona permisos predeterminados como IsAuthenticated, IsAdminUser, pero también permite definir permisos personalizados.
Gestión de Roles: La gestión de roles en DRF puede hacerse utilizando los permisos predeterminados de Django, como is_staff, o mediante Grupos y permisos personalizados.
Cool!!!
Algunos tipos de autenticación utilizados en APIs son:
Autenticación Básica: Utiliza un nombre de usuario y una contraseña codificados en Base64.
Claves API: Emplea una clave única proporcionada a cada usuario para autenticar solicitudes.
Tokens JWT (JSON Web Tokens): Utiliza tokens firmados que contienen información del usuario y tienen una duración limitada.
OAuth 2.0: Un protocolo de autorización que permite a las aplicaciones acceder a recursos en nombre del usuario sin compartir las credenciales.
Autenticación Bearer: Similar a JWT, utiliza tokens que deben ser incluidos en el encabezado de la solicitud.
gracias por compartir!
Estoy muy sorprendido de como DRF abstrae mucha lógica y hace que sea más sencillo implantar nuestros proyectos enfocándonos en la lógica de negocio y eso que se repite como los CRUDs y el sistema de Auth se reutiliza y se adapta para no crearlo desde cero (que quita mucho tiempo). MUCHAS GRACIAS LUIS.
¿Cómo se implementaría la forma de autenticación que explicó el profe Luis en un frontend?
El profesor Luis explicó el uso de 'session authentication', que implica enviar credenciales (usuario y contraseña) para obtener una cookie, luego esa cookie se envía en cada request para autenticación y autorización.
Parece que la clase permissions ha ido evolucionando y ahora también hace falta definir el método:
Yo hacia una validación para usuarios existentes previamente, pero cuando pasamos a viewsets, esta validación se complicó porque detectaba que ya existia pues los viewsets no contienen el update, me costo pero encontre esta solución muestro el codigo previo y el nuevo
previo:
def validate(self, data): first_name = data.get("first_name") last_name = data.get("last_name") qualification = data.get("qualification") patient_exists =Doctor.objects.filter( first_name__iexact=first_name, last_name__iexact=last_name, qualification__iexact=qualification
).exists()ifpatient_exists: raise serializers.ValidationError("Ya existe un doctor con el mismo nombre, apellido y qualificación.")return data
nuevo código: esto esta en el serializer
def validate(self, data): first_name = data.get("first_name") last_name = data.get("last_name") qualification = data.get("qualification") patient_exists =Doctor.objects.filter( first_name__iexact=first_name, last_name__iexact=last_name, qualification__iexact=qualification
)if self.instance: patient_exists = patient_exists.exclude(pk=self.instance.pk)if patient_exists.exists(): raise serializers.ValidationError("Ya existe un doctor con el mismo nombre, apellido y qualificación.")return data
se puede tambien personalizar el mensaje de error que utiliza django, si no pasa la autenticacion?
Seria algo así:
from rest_framework import exceptions, views, response, authentication, permissions
classCustomAuthentication(authentication.BaseAuthentication):defauthenticate(self, request):# Lógica de autenticación...if autenticacion_fallida:raise exceptions.AuthenticationFailed({'detail':'¡Credenciales inválidas! Revisa tu usuario y contraseña.'})# ...return(usuario, token)classCustomPermission(permissions.BasePermission):defhas_permission(self, request, view):ifnot request.user.is_staff:raise exceptions.PermissionDenied({'detail':'No tienes permisos para acceder a este recurso.'})returnTrue# Luego, en tu vista:classMiVista(views.APIView): authentication_classes =[CustomAuthentication] permission_classes =[CustomPermission]
Donde puedo saber mas sobre la gestión de roles? gracias de antemano