在 Mongoose 插件中从 Express 访问请求对象

问题描述 投票:0回答:1

我在 ExpressJS 中有一个 API 和一个在每个端点控制器之前执行的中间件:

app.use(segregationMiddleware);

app.get('/some-endpoint', controller1);
app.get('/some-endpoint-2', controller2);

segregationMiddleware
用于查找请求中的某些参数,然后计算一个值,然后将其作为
req.locals.domain
存储在请求对象中,以便控制器可以访问它。

在每个 Mongoose 模型中,我使用 Mongoose 插件定义了一个名为

domain
的字段(因此我不必每次都这样做)。该字段用于隔离我的资产。这意味着,例如,当
segregationMiddleware
填充
req.locals.domain = 'foo'
时,如果我制作
model.find({})
,我只想获得具有
{ domain: 'foo' }
的资产。如果我尝试更新、保存、删除等,也会发生同样的情况。

当然,我可以简单地修改每个控制器上的查询,因为我可以访问

req
,但我每次都需要这样做,并且我需要记住它以进行查找、findAndUpdate、保存等等......更快不然以后我就会忘记它。

我可以在 Mongoose 中定义一些钩子,这些钩子将使用插件修改查询,因此它将

domain
约束添加到查询中,这样我就不必在控制器中执行此操作,但我没有当前的
req
Mongoose 插件中的对象,除非我传递它,我想到的唯一方法是抽象插件中的数据库方法,所以在控制器中,我做了这样的事情:

model.safeFind(req, query);

在插件中我定义了

safeFind
,例如:

safeFind = () => {
  const theRealQuery = Object.assign({}, query, { domain: req.locals.domain });
  return this.find(query);
}

但是,这样,我需要重新定义每个数据库查询函数(find、findOne、update、save...),并且我需要记住使用安全方法。话又说回来,我迟早会忘记它。

有没有办法我仍然可以使用控制器中的常规 Mongoose 方法,并让插件以某种方式使用当前

req
对象修改每个方法的查询?

javascript node.js express mongoose
1个回答
0
投票

我的问题版本:我正在模型级别实现 ACL,其中模型在运行查询之前添加额外的过滤器以防止数据泄漏。我解决这个问题的方法是使用两个插件:

function mongoosePlugin(schema, options, callback) {
    schema.statics.setRequestData = async function(data) {
        this.request_data = data;
    };

    schema.statics.Method2 = async function(filters, options, callback) {
        console.log(this.request_data);
    };
}
SchemaName.plugin(mongoosePlugin)

在我的 Auth 中间件中,我调用

ModelName.setRequestData(req)
,然后当我需要插件内部的某些内容时,我可以访问 req。它也可以很好地与 prehooks 配合使用。

© www.soinside.com 2019 - 2024. All rights reserved.