3 minutos
Django Restframework Sistema De Permisos
Introducción
Este post es el complemento del artículo Sistema de Permisos en Django. No es una introducción a Django restframework, más bien es como implementar el sistema de autorización y autenticación en este framework.
Autorización
Se usa el mismo sistema de grupos de Django que ya se describió en el
post anterior:

Autenticación
Aquí tenemos dos opciones, usar la autenticación por nombre de usuario
y contraseña de Django, o implementar otro método como JSON Web
Token (JWT). Independientemente del sistema que usemos, el
proceso para la autenticación es el mismo.
Usar nombre de usuario y contraseña
Si nos vamos por este camino no tenemos que hacer nada extra, ya que
es el modo predeterminado de restframework.
JWT
La implementación de los JSON Web Token es muy sencilla. Primero
tenemos que agregar la dependencia del paquete simplewjt en nuestro
requirements.txt:
djangorestframework==3.11.0
coreapi==2.3.3
djangorestframework_simplejwt==4.4.0
Notas: 1) Dependiendo de la organización de tu proyecto, las dependencias pueden estar en otro archivo, en cookiecutter-django este archivo es base.txt, por dar un ejemplo. 2) Los números de versiones de las dependencias pueden variar en base a cuando leas este post.
Ahora hay que registrar a simplejwt en nuestro archivo de
configuración settings.py (o base.py, ver notas arriba):
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
}
Y esto es todo lo que tenemos que configurar para empezar a usar
JWT.
Vistas de la aplicación
Vamos a reusar las vistas del post Sistema de Permisos en Django, y las
modificaremos para usar la autenticación de restframework. La
principal diferencia es que la autenticación y autorización ya no se
especifican como Mixin al declarar la vista, ahora se usa la
variable de clase permission_classes este propósito. Aun así podemos
crear una clase que gestione la autorización:
from rest_framework import permissions
class BaseAuthPermApi(permissions.BasePermission):
def has_permission(self, request, view):
for grupo in request.user.groups.all():
if grupo.name in self._PERMISSIONS:
return True
return False
Cuando usamos restframework el método para la autorización cambia de
test_func() a has_permissions(), aunque su implementación es la
misma. También es innecesario crear una función que nos regrese una
url para el login, como lo hacíamos con get_login_url(). Ahora
podemos implementar una clase con los permisos que necesitemos:
from my_auth import BaseAuthPermApi
from django.views.generic import ListView, TemplateView
from .models import SupervisorVendedor, Venta
class PermisoGerente(BaseAuthPermApi):
_PERMISSIONS = ['GERENTE']
class PermisoSupervisor(BaseAuthPermApi):
_PERMISSIONS = ['VENDEDOR', 'SUPERVISOR']
class IndexView(TemplateView)
template_name = 'homepage.html'
class VentasView(ListView):
permission_classes = [PermisoGerente & permissions.IsAuthenticated]
model = Venta
template_name = 'ventas/ventas_sin_filtro.html'
class VentasFiltradasView(ListView):
permission_classes = [PermisoSupervisor & permissions.IsAuthenticated]
template_name = 'ventas/ventas_con_filtro.html'
def get_queryset(self):
grupos = self.request.user.groups.all()
user_id = self.request.user.id
if 'VENDEDOR' in grupos:
ids = user_id
elif 'SUPERVISOR' in grupos:
ids = SupervisorVendedor.objects.filter(user_id=user_id).values_list(
'vendedor_id', flat=True)
ventas = Venta.objects.filter(vendedor_id__in=ids)
return {'ventas': ventas}
Independientemente de si usamos el sistema de usuario y contraseña, o
si usamos JWT nuestras vistas quedan igual.
Conclusión
La implementación de la autenticación y autorización usando
restframework es muy simple y no varía mucho del plain
Django. Como pudimos ver en el código de las vistas solo hay que
quitar el mixin de la autorización de la clase, e implementar la
variable permission_classes para indicar los permisos y si queremos
o no que el usuario esté autenticado.