Saltar a contenido

Roles

En el apartado de middlewares se explicaba que estos intervienen en acciones que permiten interceptar y/o modificar el flujo de datos.

En esta entrada, nos enfocaremos en la validación de roles, utilizando la clase HasRoles.

Disponible en el módulo app.common.middlewares.sessions

Nota

  • Te recomendamos leer, el apartado de Inyección de Dependencias.
  • Es necesario utilizar la dependencia (Depend) validate_auth_session, para que esta clase funcione en un route.

HasRoles es una clase utilizada como Inyección de Dependencias, para realizar las siguientes operaciones:

Definición

  • chequea que al menos uno de los roles exista, en la lista de roles enviados por la vista.

  • si no se envía ningún rol, se asigna y se valida el rol de menor privilegio, AuthRoles.ANONYMOUS_USER.

  • obtiene los datos a validar, del objeto request.state para más información, consulta la función validate_auth_session en app.common.middlewares.auth.

  • inyecta en el route, el rol del obtenido de la sesión, ó None en caso de error.

Las dependencias no tienen que ser funciones; también pueden ser clases. Al declarar HasRoles como clase, FastAPI la instanciará y le inyectará los parámetros necesarios cuando se use.

1
2
3
4
5
6
7
8
from app.common.middlewares.sessions import HasRoles
...

async def customers_create(
    request: Request,
    roles: Optional[str] = Depends(HasRoles(["GOTU", "COMPANY_OWNER", "REGULAR_USER"])),
):
    ...

la clase HasRoles buscará en el objeto request.state si existe una llave llamada role y verifica que al menos uno, de los roles de la lista enviada, exista, en esta llave.

Nota

veamos un ejemplo:

agregamos la dependencia validate_auth_session:

1
2
3
4
5
6
7
# app/modules/customers/urls.py

from fastapi import Depends
from app.common.middlewares.auth import validate_auth_session
...

add_router(customers_router, "/customers", tags=["customers"], dependencies=[Depends(validate_auth_session)])

utilizamos HasRoles en un route:

# app/modules/customers/views/customers_view.py

from fastapi import APIRouter, Depends, Request
from app.common.middlewares.sessions import HasRoles
...

customers_router = APIRouter()

@customers_router.post("")
@customers_router.post("/")
async def customers_create(
    request: Request,
    body: CustomersCreateDto,
    roles: Optional[str] = Depends(HasRoles(["GOTU"])),
):
    try:
        ...

        logger.info("customers_create role: {}", roles)

        return response(201, HTTPStatus.CREATED, result)
    except Exception as e:
        logger.exception("customers_router.post customers_create Exception: {}", e)
        return response(400, HTTPStatus.UNEXPECTED_ERROR, error=str(e))

Recuerda

Recuerda utilizar la dependencia (Depend) validate_auth_session, para que esta clase funcione correctamente en un route, de lo contrario generará un error al validar el rol.

Lectura recomendada