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.