简体   繁体   English

如何跨多个模块访问节点acl?

[英]How to access node acl across multiple modules?

I am having some trouble understanding how to use the Node ACL with mongoose module. 我在理解如何将节点ACL与mongoose模块一起使用时遇到了一些麻烦。 I can get it running fine as long as everything is in one file. 只要所有内容都在一个文件中,我就可以正常运行。 However how do I access the acl instance in other modules if I wanted to break up the routes into separate files? 但是,如果我想将路由拆分为单独的文件,如何访问其他模块中的acl实例?

I can get acl working with the following code just fine. 我可以让acl使用以下代码就好了。 It initializes, creates the collections in the database, and adds permissions to the user. 它初始化,在数据库中创建集合,并向用户添加权限。

// App.js
const mongoose = require('mongoose');
const node_acl = require('acl');
const User = require('./models/User');

mongoose.connect(/* connection string */);

acl = new node_acl(new node_acl.mongodbBackend(mongoose.connection.db, '_acl'));
acl.allow([
  {
    roles: ['guest'],
    allows: [{ resources: 'login', permissions: 'get' }],
  },
  {
    roles: ['admin'],
    allows: [{ resources: '/users', permissions: '*' }]
  }
]);

var user = User.findOne({username: 'coffee'}, (err, user) => {
  console.error(user.id);
  acl.addUserRoles(user.id, 'admin');
});

What I can't figure out is how to properly access the acl instance in another module like this. 我无法弄清楚的是如何正确访问另一个模块中的acl实例。

// routes/foo.js
const acl = require('acl');
const router = require('express').Router();

// initialize acl ?

router.route('/', acl.middleware(/* rules */), (req, res) => {
  // route logic
});

module.exports = router;

This code yields the following error: TypeError: acl.middleware is not a function . 此代码产生以下错误: TypeError: acl.middleware is not a function

Do I need to create a new instance of acl using the database connection in each route module? 我是否需要在每个路由模块中使用数据库连接创建新的acl实例? If so what is the best way to to get the connection from Mongoose again? 如果是这样,从Mongoose再次获得连接的最佳方法是什么? If not, or is there a way to pass it to each route? 如果没有,或者有没有办法将它传递给每条路线?

Thank you! 谢谢!

You can share object by request variable: 您可以按请求变量共享对象:

app.js: app.js:

acl = new node_acl( new node_acl.mongodbBackend(mongoose.connection.db, '_acl'));
// add this before routers:
app.use( function( req, res, next) {
  req.acl = acl;
  next();
}); 

routes/foo.js: 路线/ foo.js:

router.route('/', (req, res) => {
  console.log(req.acl);
  // route logic
});  

As IOInterrupt suggested you should create a helper module, here's is how i made it work: 正如IOInterrupt建议你应该创建一个帮助器模块,这就是我如何使它工作:

security.js security.js

'use strict';

var node_acl = require('acl'),
    log = require('../log')(module),
    redis = require('../db/redis'),
    acl;

var redisBackend = new node_acl.redisBackend(redis, 'acl');
acl = new node_acl(redisBackend, log);
set_roles();

function set_roles () {

    acl.allow([{
        roles: 'admin',
        allows: [{
                resources: '/api/conf',
                permissions: '*'
            }
        ]
    }, {
        roles: 'user',
        allows: [{
            resources: 'photos',
            permissions: ['view', 'edit', 'delete']
        }]
    }, {
        roles: 'guest',
        allows: []
    }]);

    acl.addUserRoles('5863effc17a181523b12d48e', 'admin').then(function (res){
        console.log('Added myself ' + res);
    }).catch(function (err){
        console.log('Didnt worked m8' + err);
    });

}

module.exports = acl;

i called it for the first time on my app.js 我第一次在我的app.js上调用它

app.js app.js

// .. a bunch of other stuff 
var app = express();

require('./config/express')(app);
require('./config/routes')(app, jwtauth.jwtCheck);
require('./config/security'); // just like this

connect().on('error', console.log)
         .on('disconnected', connect)
         .once('open', function (){
            log.info('Connected to DB!!!');
         });
// .. a bunch of other stuff 

Then on my route file conf.js like this: 然后在我的路由文件conf.js上像这样:

conf.js conf.js

    log = require(libs + 'log')(module),
    acl = require('../config/security'),
    isauth = require(libs + 'auth/isAuthorized'),
    redis = require('../db/redis');

//               This is where the magic ensues
router.get('/', acl.middleware(2,isauth.validateToken,'view'), function (req, res) {
    Conf.findById(req.query.id).then(function (conf) {
        return res.json(conf);
    }).catch(function (err) {

Don't worry about calling the mongo connection to being called at each import, since here you'll be using require('../config/security') so they will all get the same object because exports is cached during the first time you call it at app.js . 不要担心在每次导入时调用mongo连接被调用,因为在这里你将使用require('../ config / security')所以它们将获得相同的对象,因为导出在第一次被缓存你在app.js上调用它。 I mean, this will not create a mongodb connection each time. 我的意思是,每次都不会创建一个mongodb连接。

I would suggest creating a helper module, which initializes the acl. 我建议创建一个辅助模块,初始化acl。 You could then require it within any other modules that may require it, such as your routes. 然后,您可以在可能需要它的任何其他模块中要求它,例如您的路线。

You can use app.locals to store global object within the application., 您可以使用app.locals在应用程序中存储全局对象。

in your app.js : 在你的app.js

app.locals.acl = acl;

then in any request, you can get it back by req.app.locals.acl : 然后在任何请求中,您可以通过req.app.locals.acl获取它:

route.get('/some-resource', function (req, res, next) {

    let acl = req.app.locals.acl
    ...
}

Checkout app.locals document at https://expressjs.com/en/api.html#app.locals https://expressjs.com/en/api.html#app.locals上查看app.locals文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM