【问题标题】:node.js data access acl permissionnode.js数据访问acl权限
【发布时间】:2018-12-08 01:43:08
【问题描述】:

您好,谁能帮帮我。我希望用户只能访问他们被允许访问的内容。

我一直在研究几个访问控制列表包。我还没有做出最终决定。

拥有多个权限级别的餐厅。

  1. 客户可以下多个订单,并且可以查看他订购了哪些食物

  2. 他也可以只在指定的时间段内修改订单,例如在处理订单之前。

  3. 客户只能查看自己的订单和订单所处的阶段。

  4. 工作人员只能检查菜单下的订单,并说明订单的费用和订单需要多长时间。

  5. 另一名员工将负责商店以及物品的进出方式。

  6. 员工可以负责一个部门,同时允许输入另一个部门下的菜单。

我一直在研究如何将其放入 Express.js 和 mongodb

我看了以下

https://github.com/optimalbits/node_acl主要焦点

https://www.npmjs.com/package/acl https://www.npmjs.com/package/express-acl

但是我没有得到我上面所说的粒度和混合。

许可主要基于数据。我如何才能做到这一点有点令人困惑。

任何帮助都会很有用

我使用猫鼬作为我的驱动程序

【问题讨论】:

  • 您将访问控制与业务规则混为一谈。 ACL 特别适合描述用户拥有(或没有)读取/修改给定对象的权限。他们不擅长验证修改是否适当(例如基于对象的状态)。
  • 请问我怎样才能实现我的目标?任何帮助或指导将不胜感激

标签: node.js mongodb express acl


【解决方案1】:

正如我在 cmets 中所说,这种设计有一些业务逻辑,可能使其不适合常规 ACL 类型的安全控制。从表面上看,似乎更容易找出解决方案是在 Mongoose 模型或控制器代码中实现您的业务规则,具体取决于您的偏好。也就是说,使用类似 ACL 的方法执行任何操作的关键在于您的 URL 设计。例如,很容易让您的 API 使所有订单都可以通过/api/orders 获得,并且可能有人会通过/api/orders?userId=12345 查询他们自己的订单。但这使得大多数基于 ACL 的方法都失败了。相反,您必须根据需要保护的层次结构来考虑 API(无论是否所有订单都存储在 Orders Mongoose 模型中,并保留在订单集合中)。

所以以你的第一个需求为例

客户可以下多个订单,并且可以查看他订购了哪些食物

这里的重点是您通过订单的客户“所有者”来保护事物,因此要以这种方式保护它,您需要以这种方式设置您的路线,例如(假设您使用的是您询问的第一个中间件):

app.post('/api/customer/:customerId/orders', acl.middleware(), (req, res, next) => { 
  const order = new Order(req.body); // TODO: whitelist what info you take in here
  order.customerId = req.user.id; // assuming you have a logged-in user that does this
  order.save(e => {
    if (e) return next(e);
    return res.status(201).send(order);
  });  
});

为了支持这一点,您需要这样注册您的 ACL 信息:

acl.allow('12345', '/api/customer/12345/orders', ['post']); 

至少,你会这样做。您可能会提供更多选项,例如“获取”等。您可以猜到,这意味着您需要在创建单个用户时为它们注册权限(以支持“所有权”的概念)。

对于您的第二个要求,

他也可以只在指定的时间段内修改订单,例如在处理订单之前。

尽管我之前说过,如果您真的想这样做,可以说可以在 ACL 中执行此操作。例如,您可以为状态创建 URL 帐户,例如“/api/customers/12345/orders/modifiable/6789”,但根据我的经验,这很难维护。您最好将该逻辑放在控制器或 Mongoose 逻辑中。除非您打算在 Express 应用程序之外使用 Mongoose 模型,否则在控制器中执行此操作可能更简单。像这样的东西(注意,在这种情况下不使用 ACL,但如果你愿意,你可以使用):

app.param('orderId', (req, res, next, id) => {
  Order.findById(id, (err, order) => {
    if (err) return next(err);
    if (order) {
      req.order = order;
      return next();
    }
    const notFound = new Error('Order not found');
    notFound.status = 404;

    return next(notFound);
  });
});

app.put('/api/orders/:orderId', (req, res, next) => {
  if (req.order.status !== 'pending') {// or whatever your code setup is
    const notProcessable = new Error('Cannot modify an order in process');
    notProcessable.status = 422;
    return next(notProcessable);
  }

  // handle the modification and save stuff
});

【讨论】:

  • 非常感谢。我很感激。我会尝试一下,然后就结果回复你。我非常感谢您为帮助我所做的努力。奇怪的是它看起来很简单。
  • 我非常感谢您的帮助,尽管我无法使用我必须编写自己的任何 acl 以适应我的代码。我仍然会接受答案
  • @SMev 不客气。我确实说它不太适合 ACL 库... ;)
  • 希望我没有打扰。你知道如何解决这个问题吗? stackoverflow.com/questions/53857561/…
猜你喜欢
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
相关资源
最近更新 更多