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

我有一些麻烦了解如何使用mongoose模块使用节点ACL 。 只要一切都在一个文件中,我就可以很好地运行。 但是,如果我想将路由分解成单独的文件,我怎样才能访问其他模块中的acl实例?

我可以得到acl与下面的代码工作就好了。 它初始化,在数据库中创build集合,并向用户添加权限。

// 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'); }); 

我无法弄清楚如何正确访问另一个模块中的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; 

此代码会产生以下错误: TypeError: acl.middleware is not a function

我是否需要在每个路由模块中使用数据库连接创build一个新的acl实例? 如果是这样,再次从Mongoose获得连接的最佳方式是什么? 如果没有,还是有办法将它传递给每条路线?

谢谢!

由于IOInterruptbuild议你应该创build一个辅助模块,下面是我如何工作:

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; 

我第一次在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 

然后在我的路由文件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) { 

不要担心在每个导入时调用mongo连接,因为在这里您将使用require('../ config / security'),因此它们将获得相同的对象,因为导出在第一次被caching你可以在app.js中调用它。 我的意思是,这不会每次都创build一个mongodb连接。

你可以通过请求variables来共享对象:

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(); }); 

路线/ foo.js:

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

我会build议创build一个辅助模块,初始化acl。 然后,您可以在任何其他可能需要的模块(如您的路线)中要求它。

您可以使用app.locals将全局对象存储在应用程序中。

在你的app.js

 app.locals.acl = acl; 

那么在任何请求中,你都可以通过req.app.locals.acl来获取它:

 route.get('/some-resource', function (req, res, next) { let acl = req.app.locals.acl ... } 

https://expressjs.com/en/api.html#app.locals签出app.locals文件