Django Auth (Roles y Modelo Relacional)
Es aconsejable que antes de profundizar en este post se comprenda como funciona la interfaz de admin que Django tiene por defecto en la ruta http://localhost:8000/admin/
Roles (Grupos)
Si algo me inquieta bastante, es no comprender que esta pasando bajo cualquier contexto. Antes, mi historia (Ads 😛), tengo pensado el uso de Django como Backend, en la mayoria de proyectos se debe asignar roles a cada usuario, pero Django ya lo tiene implementado y se llama agrupación (Groups), figura 1.
Este grupo contiene todas las acciones (Permisos) que se tienen en las entidades del proyecto, en este caso estoy creando un grupo llamado
“admin” y tiene las acciones que están en la parte derecha de la figura 1.
Existen un montón de permisos (Acciones) que Django ya trae por defecto, a medida que vayas desarrollando y aumentando entidades, esta lista se hará más grande.
Dicho grupo es asignable a cualquier usuario, desde ese momento el usuario asignado solo podrá realizar las acciones o permisos predefinidos en el grupo.
En la figura 2, el grupo “admin” que creé esta siendo asignado a un determinado usuario, sin embargo, en la parte inferior se sigue observando los permisos que existen en la figura 1, ¿Qué quiere decir esto? ¡Correcto!, existe redundancia de permisos y los divide en grupales e individuales, ¿Por qué? imagínate tener una aplicación de libros y en el un grupo (Rol) llamado “lector” que solo puede acceder a la sección de libros y leerlos, tu app funcionaba de maravilla con esa característica, pero un salvaje día los requerimientos cambian repentinamente, la competencia es fuerte y toca usar cupones de todo tipo con el fin de dar a los usuarios cierta característica VIP (Publicación, consejos, comentarios, stickers, etc), pero no toda (Business son business 😆), entonces, el usuario que antes encajaba con el grupo (Rol) de “lector”, ahora encaja en algo como semi-VIP, pero no necesariamente “VIP”, por lo cual necesitará solamente algunos permisos VIP, además, dichos cupones serán momentáneos y posiblemente cambien o desaparezcan. Cuando tienes una aplicación grande y los cambios requeridos son urgentes, toca usar este pequeño comodín (es aconsejable definir anticipadamente cada rol o grupo).
Modelo Relacional
Algo negativo de Django es que no cuente con una gráfica del modelo relacional de su migración inicial por defecto en su documentación oficial. Un modelo nos puede ahorrar el tiempo de comprender el framework o satisfacer las dudas ante la necesidad de personalizar el Auth que ya existe.
Indirectamente ya vimos la mayoría de las entidades que trabajan inicialmente en Django, pero acá les dejo un resumen:
- auth_user, entidad que aloja los usuarios.
- auth_permision, entidad que aloja los permisos que a su vez esta en función al tipo de contenido (auth_content_type).
- auth_content_type, entidad que hace de almacén de nombres y tipos de las demás entidades, existe con el fin de darle al framework mayor expresividad.
- auth_group_permisions, entidad que agrupa los permisos (auth_permision) y es lo que denominamos como Rol.
- auth_group, entidad que refleja los grupos de permisos (Roles), es una entidad que en mi opinión esta demás, ya que solo contiene el nombre del grupo de permisos (Roles) que podría estar en auth_group_permisions, pero me imagino que es así con fines prácticos al momento de visualizarlos en la interfaz admin.
- auth_user_groups, entidad que aloja a que grupo (Rol) pertenece el usuario.
- auth_user_user_permissions, entidad bypass (El comodín) para obtener permisos sin necesidad de pertenecer a un grupo en específico.
- django_admin_log, entidad para el seguimiento y registro de las acciones que realiza el usuario, en otras palabras hace de logger.
- django_sesions, entidad para el registro de sesiones (tiempo y caducidad de una sesión).
- django_migrations, entidad para el registro de las migraciones o modificaciones que se hace a la base de datos con el framework.
Dar un pasito más allá en Auth es hacer el uso de Tokens (códigos de seguridad), esta práctica permite no tener que involucrar las credenciales (usuario y contraseña) al realizar las peticiones http a una API (en este caso Django), lo cual reduce sustancialmente la posibilidad de comprometer las credenciales de cualquier usuario en el proceso de petición, les dejo un post que explica e implementa dichos Tokens en Django.
Con ese paso más el modelo relacional queda así:
Solo se incrementa una nueva entidad (authtoken_token); en la práctica luce así:
ec918b356a14e633c74f6a5fa331b183dbdc7da7
Todo usuario debería tener al menos uno y se incrementa al header de cualquier petición http, para no trabajar con el usuario y contraseña:
Eso es todo, hasta luego 👋 y como de costumbre les dejo un mensaje:
No eres lo que tienes, sino lo que haces con lo que tienes.