使用 MEAN.JS 用户授权

Posted

技术标签:

【中文标题】使用 MEAN.JS 用户授权【英文标题】:Working with MEAN.JS users authorization 【发布时间】:2015-10-25 19:47:10 【问题描述】:

我已经开始使用 MEAN.js 全栈解决方案来学习如何创建 Web 应用程序。

我已经使用生成器创建了几个 CRUD 模型,它已经生成了所有的快速路线等......

它还创建了一个用户模型作为模板,其中包含一些角色和一些经过身份验证和授权的中间件。

我想稍微调整中间件,但我不知道最好的方法。

对于我的一个模型(称为主题公园),我想确保用户不仅已登录,而且还根据他们的角色获得授权以执行发布操作。

下面的代码是我目前从生成器获得的代码,正如您所见,'/themeparks/:themeparkId' 路由具有 themeparks.hasAuthorization 中间件函数调用。但是,这不适用于“/themeparks”路线,也不适用于 users.hasAuthorization 中间件功能。

所以我想知道将用户授权添加到“/themeparks”路线的 post 方法的最佳方法是什么?或许还有一些包含教程或涵盖 MEAN.js 堆栈中的用户模型的资源?

//路线

'use strict';

module.exports = function(app) 
var users = require('../../app/controllers/users.server.controller');
var themeparks = require('../../app/controllers/themeparks.server.controller');

// Themeparks Routes
app.route('/themeparks')
    .get(themeparks.list)
    .post(users.requiresLogin, themeparks.create); //<----How do I add authorization based on a role here??

app.route('/themeparks/:themeparkId')
    .get(themeparks.read)
    .put(users.requiresLogin, themeparks.hasAuthorization, themeparks.update)
    .delete(users.requiresLogin, themeparks.hasAuthorization, themeparks.delete);

// Finish by binding the Themepark middleware
app.param('themeparkId', themeparks.themeparkByID);
;

//用户中间件

/**
 * Require login routing middleware
 */
exports.requiresLogin = function(req, res, next) 
    if (!req.isAuthenticated()) 
        return res.status(401).send(
            message: 'User is not logged in'
        );
    

    next();
;

/**
 * User authorizations routing middleware
 */
exports.hasAuthorization = function(roles) 
    var _this = this;

    return function(req, res, next) 
        _this.requiresLogin(req, res, function() 
            if (_.intersection(req.user.roles, roles).length) 
                return next();
             else 
                return res.status(403).send(
                    message: 'User is not authorized'
                );
            
        );
    ;
;

//主题公园中间件

/**
 * Themepark middleware
 */
exports.themeparkByID = function(req, res, next, id)  //TODO: This is probably what is pulling the user in through the middleware.
    Themepark.findById(id).populate('user', 'displayName').exec(function(err, themepark) 
        if (err) return next(err);
        if (! themepark) return next(new Error('Failed to load Themepark ' + id));
        req.themepark = themepark ;
        next();
    );
;

/**
 * Themepark authorization middleware
 */
exports.hasAuthorization = function(req, res, next) 
    if (req.themepark.user.id !== req.user.id) 
        return res.status(403).send('User is not authorized');
    
    next();
;

【问题讨论】:

【参考方案1】:

你以同样的方式添加中间件:

app.route('/themeparks')
.get(themeparks.list)
.post(users.requiresLogin, themeparks.userRoleHasAuthorization, themeparks.create);

在主题公园模块中,您添加此功能,就像 hasAuthorization 功能一样,还包括检查用户是否在角色中。您已经从请求中获得了用户 ID。使用它来查询用户可以从数据库中访问的角色。

(理想情况下,如果角色在数据库中,我会在检索用户对象本身时检索它,这样前端也可以在需要时使用角色信息,而您不必在其中查询授权模块。)

根据用户 ID,角色信息确定用户是否具有允许更新此模块的角色。否则返回 401 Not Authorized。以下是构建代码的方法。 canUpdate 函数需要根据您希望如何存储角色以及应该有权访问角色的模块的信息来实现。

exports.userRoleHasAuthorization = function(req, res, next) 
if (req.themepark.user.id !== req.user.id || !canUpdate(req.user.id, 'themeparks') 
    return res.status(403).send('User is not authorized');

next();
;

【讨论】:

以上是关于使用 MEAN.JS 用户授权的主要内容,如果未能解决你的问题,请参考以下文章

Sudo使用(linux用户授权)

Slack Oauth:如果用户已经授权应用程序,则自动授权用户

mysql 一个账户能授权几个ip

小程序-用户授权/授权后的信息读取流程

求助,MySql 5.6.17 授权用户问题

Laravel使用policy完成用户授权