javascript - How to access node acl across multiple modules? - Stack Overflow

I am having some trouble understanding how to use the Node ACL with mongoose module. I can get it runni

I am having some trouble understanding how to use the Node ACL with mongoose module. 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?

I can get acl working with the following code just fine. 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.

// 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.

Do I need to create a new instance of acl using the database connection in each route module? If so what is the best way to to get the connection from Mongoose again? If not, or is there a way to pass it to each route?

Thank you!

I am having some trouble understanding how to use the Node ACL with mongoose module. 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?

I can get acl working with the following code just fine. 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.

// 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.

Do I need to create a new instance of acl using the database connection in each route module? If so what is the best way to to get the connection from Mongoose again? If not, or is there a way to pass it to each route?

Thank you!

Share Improve this question asked Feb 11, 2016 at 14:00 JeremyCJeremyC 3414 silver badges14 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

You can share object by request variable:

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:

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:

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

// .. 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

    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. I mean, this will not create a mongodb connection each time.

I would suggest creating a helper module, which initializes the 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.,

in your app.js:

app.locals.acl = acl;

then in any request, you can get it back by 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./en/api.html#app.locals

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745215537a4616996.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信