Modelo de seguridad de permisos de usuario de Node.js + Express.js

79

Tenemos una aplicación que tiene dos tipos de usuarios. Dependiendo de cómo inicie sesión el usuario, queremos que tenga acceso a diferentes partes de la aplicación.

¿Cómo implementamos un modelo de seguridad para evitar que los usuarios vean cosas a las que no tienen acceso?

¿Hacemos de la seguridad parte de la implementación de cada ruta? El problema es que tendremos lógica duplicada en las solicitudes. Podríamos mover esto a funciones auxiliares, pero aún tendríamos que recordar llamarlo.

¿Hacemos que la seguridad sea parte de un controlador de ruta global app.all ()? El problema es que tenemos que inspeccionar cada ruta y hacer una lógica diferente basada en una multitud de reglas. Al menos todo el código está en un solo lugar, pero luego ... todo el código está en un solo lugar.

Parques de Travis
fuente

Respuestas:

137

Tenerlo por ruta generalmente funciona para mí. Esto es lo que hago normalmente:

function requireRole (role) {
    return function (req, res, next) {
        if (req.session.user && req.session.user.role === role) {
            next();
        } else {
            res.send(403);
        }
    }
}

app.get("/foo", foo.index);
app.get("/foo/:id", requireRole("user"), foo.show);
app.post("/foo", requireRole("admin"), foo.create);

// All bars are protected
app.all("/foo/bar", requireRole("admin"));

// All paths starting with "/foo/bar/" are protected
app.all("/foo/bar/*", requireRole("user"));
Linus Thiel
fuente
Pero, ¿y si solo 2 roles pueden acceder a la ruta?
Vladimir Djukic
1
¿Podrías hacer requireRoletomar una matriz en su lugar? Y consulte con indexOf.
Linus Thiel
¿Podría agregar un ejemplo? ¿Esta última ruta protege todas las rutas que comienzan con / foo / bar?
Vladimir Djukic
¿Qué pasa si se cambian los permisos en la base de datos? ¿Cómo asegurarse de que la sesión sea coherente con la base de datos?
nomadoda
2
@nomadoda, me parece un problema un poco diferente, pero tendrías que actualizar la sesión de alguna manera. Depende de la tienda de respaldo de sesión que use, lo más fácil sería permitir que el usuario inicie sesión nuevamente después de ese tipo de cambio.
Linus Thiel
7

Eche un vistazo a esta lista para los sistemas de permisos / ACL de NodeJS. En mi humilde opinión, OptimalBits node_acl se ve mejor.

McMeep
fuente
1
¿Existe una lista más reciente de módulos ACL de Node.js? Estamos considerando cómo implementar ACL en una aplicación Meteor.js.
Brylie Christopher Oxley
3

Ahora hay permiso de módulo de nodo para esto. Es muy fácil de usar, muy similar a la respuesta aceptada, pero aún se agregan algunas características.

Tommz
fuente