MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Ruoli utente e autorizzazioni Express.js/Mongoose

Ho trovato una soluzione. Sarebbe bello sentire le opinioni della gente su questo.

Ho un oggetto di configurazione delle autorizzazioni che definisce ogni ruolo e le relative autorizzazioni.

Oggetto di configurazione autorizzazioni

roles.admin = {
    id: "admin",
    name: "Admin",
    description: "",
    resource : [
        {
            id : 'blog', 
            permissions: ['create', 'read', 'update', 'delete']
        },
        {
            id : 'user',
            permissions: ['create', 'read', 'update', 'delete']
        },
        {
            id : 'journal',
            permissions: ['create', 'read', 'update', 'delete']
        },

    ]
};

roles.editor = {
    id: "editor",
    name: "Editor",
    description: "",
    resource : [
        {
            id : 'blog', 
            permissions: ['create', 'read', 'update', 'delete']
        },
        {
            id : 'user',
            permissions: ['read']
        },
        {
            id : 'journal',
            permissions: ['create', 'read', 'update']
        },

    ]
};

Funzione middleware

var roles = require('./config');


var permissions = (function () {

  var getRoles = function (role) {

    var rolesArr = [];

    if (typeof role === 'object' && Array.isArray(role)) {

        // Returns selected roles   
        for (var i = 0, len = role.length; i < len; i++) {
            rolesArr.push(roles[role[i]]);
        };
        return rolesArr;

    } else if (typeof role === 'string' || !role) {

        // Returns all roles
        if (!role) {
            for (var role in roles) {
                rolesArr.push(roles[role]);
            };
        }   

        // Returns single role
        rolesArr.push(roles[role]);
        return rolesArr;

    }

},
check = function (action, resource, loginRequired) {

    return function(req, res, next) {

        var isAuth = req.isAuthenticated();

        // If user is required to be logged in & isn't
        if (loginRequired  && !isAuth) {
            return next(new Error("You must be logged in to view this area"));
        }

        if (isAuth || !loginRequired) {

            var authRole = isAuth ? req.user.role : 'user', 
                role =  get(authRole),
                hasPermission = false;

            (function () {
                for (var i = 0, len = role[0].resource.length; i < len; i++){
                    if (role[0].resource[i].id === resource && role[0].resource[i].permissions.indexOf(action) !== -1) {
                        hasPermission = true;
                        return;
                    }
                };
            })();

            if (hasPermission) {
                next();
            } else {
                return next(new Error("You are trying to " + action + " a " + resource + " and do not have the correct permissions."));
            }

        }
    }
}

return {
    get : function (role) {

        var roles = getRoles(role);

        return roles;
    },
    check : function (action, resource, loginRequired) {
        return check(action, resource, loginRequired);
    }
}

})();

module.exports = permissions;

Quindi ho creato una funzione middleware, quando il controllo viene chiamato ottiene il ruolo degli utenti da req oggetto (req.utente.ruolo). Quindi esamina i parametri passati al middleware e li incrocia con quelli nell'oggetto di configurazione dei permessi.

Percorso con middlware

app.get('/journal', `**permissions.check('read', 'journal')**`, function (req, res) {
     // do stuff
};