Node.js

Node

Tutorial Node: Roles y permisos

Node.js: Guía práctica para implementar control de accesos por rol mediante middleware personalizado. Aprende a gestionar roles de usuario.

Aprende Node GRATIS y certifícate

Control de accesos por rol (middleware personalizado)

En Node.js, un middleware se puede encargar de validar el rol de un usuario antes de permitir el acceso a ciertos recursos. Este enfoque consiste en interceptar la petición entrante, comprobar el rol del usuario y decidir si se continúa con la ejecución de la siguiente función o se devuelve un mensaje de error. Al usar un middleware dedicado, se separa la lógica de autorización del resto del código y se facilita el mantenimiento.

Para implementar este proceso, es habitual definir una función que reciba una lista de roles permitidos. Dicha función retornará otro middleware que verifique si el rol del usuario coincide con alguno de los permitidos. Si el rol no está autorizado, la respuesta finalizará con un estado de error; si está autorizado, se invoca a la siguiente función. Por ejemplo:

// middlewares/authorization.mjs
export function verifyRole(allowedRoles) {
    return function (req, res, next) {
        const userRole = req.user?.role; // Assuming req.user contains the role
        if (!userRole || !allowedRoles.includes(userRole)) {
            return res
                .writeHead(403, { "Content-Type": "text/plain" })
                .end("Access denied due to insufficient role");
        }
        next();
    };
}

En este ejemplo, se comprueba si rolUsuario está presente y coincide con alguno de los rolesPermitidos. Es aconsejable mantener la lista de roles en un lugar centralizado para simplificar el control de cambios futuros y mejorar la consistencia del proyecto. También resulta útil combinar este middleware con otros validadores, como la comprobación de un token o de credenciales.

Una forma de integrarlo en las rutas es incluirlo como una capa adicional de seguridad. Por ejemplo, supongamos que tenemos un módulo de rutas donde deseamos restringir el acceso a un recurso sensible. Podemos usar el middleware en cada ruta de este modo:

import { createServer } from "http";
import { verifyRole } from "./middlewares/authorization.mjs";

createServer((req, res) => {
    if (req.url === "/admin" && req.method === "GET") {
        // Conjunto de roles con acceso
        const allowedRoles = ["admin", "superuser"];

        // Se invoca el middleware
        verifyRole(allowedRoles)(req, res, () => {
            res.writeHead(200, { "Content-Type": "text/plain" }).end("Admin content");
        });
    } else {
        res.writeHead(404, { "Content-Type": "text/plain" }).end("Resource not found");
    }
}).listen(3000, () => {
    console.log("Server listening on port http://localhost:3000");
});

En el fragmento anterior, el módulo http maneja la petición y, antes de responder, llama al middleware para determinar si el usuario tiene la autorización necesaria. Si supera la validación, la función de callback se encarga de responder; de lo contrario, se devuelve un estado HTTP 403. Este método resulta escalable cuando se maneja un volumen alto de rutas y se desea disponer de un control de accesos más granular.

Manejo de múltiples roles

La asignación de múltiples roles a un mismo usuario permite controlar los recursos de manera granular y adaptada a distintos perfiles dentro de un proyecto. De este modo, si una persona asume varias responsabilidades, su conjunto de privilegios se combina para que mantenga acceso a las acciones correspondientes a cada uno de sus permisos.

Un enfoque para manejar permisos de manera flexible consiste en almacenar los distintos roles del usuario en un array y, en tiempo de ejecución, comprobar si alguno de esos roles proporciona acceso a la ruta o recurso solicitado. Por ejemplo, un usuario podría tener roles como "editor" y "admin", y se requeriría al menos uno de esos roles para acceder a determinadas secciones protegidas.

En sistemas de seguridad más avanzados, es frecuente añadir lógica adicional para determinar el nivel de acceso específico de cada rol, como restringir ciertas operaciones críticas. Es recomendable mantener una única fuente de definición de todos los roles y sus correspondientes acciones permitidas, para que el control sea coherente en todas las rutas y servicios que demandan autorizaciones complejas.

A continuación, se muestra un ejemplo de validación en Node.js donde un usuario puede tener varios roles y se emplea una única comprobación para decidir los accesos:

import { createServer } from "http";

createServer((req, res) => {
    // Supongamos que req.user contiene un array con los roles del usuario
    const userRoles = req.user?.roles || [];

    if (req.url === "/special-content" && req.method === "GET") {
        // Roles que pueden acceder a este endpoint
        const requiredRoles = ["admin", "supervisor"];

        // Se verifica si el usuario tiene al menos uno de los roles requeridos
        const allowed = userRoles.some((role) => requiredRoles.includes(role));

        if (!allowed) {
            res.writeHead(403, { "Content-Type": "text/plain" });
            return res.end("Access denied. Insufficient role.");
        }

        res.writeHead(200, { "Content-Type": "text/plain" });
        return res.end("Special content available for your role.");
    }

    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("Resource not found.");
}).listen(3000, () => {
    console.log("Server running on port http://localhost:3000");
});

En este código se evalúa la presencia de cualquiera de los roles requeridos en el array del usuario. Si no hay coincidencias, se devuelve un estado HTTP 403 como rechazo; de lo contrario, se concede el acceso. De esta forma, la infraestructura sigue un patrón homogéneo de validación, independientemente de la cantidad de roles que se manejen en el sistema.

Para seguir leyendo hazte Plus

¿Ya eres Plus? Accede a la app

Plan mensual

19.00 € /mes

Precio normal mensual: 19 €
47 % DE DESCUENTO

Plan anual

10.00 € /mes

Ahorras 108 € al año
Precio normal anual: 120 €
Aprende Node GRATIS online

Todas las lecciones de Node

Accede a todas las lecciones de Node y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Node y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender el concepto de middleware en Node.js.
  2. Implementar un middleware para autorizar por rol.
  3. Gestionar múltiples roles por usuario.
  4. Crear lógica de control de acceso segura.