【问题标题】:Can a middleware return middlewares in Express中间件可以在 Express 中返回中间件吗
【发布时间】:2021-11-30 02:43:05
【问题描述】:

我正在尝试将不同的中间件(此处为 multer 和 auth0)组合在一起以降低代码复杂性。我可以编写一个返回中间件或仅返回 next() 的中间件(如果环境/参数不需要执行)。

类似这样的:

const constraints = {
    'local': {
        'GET': {},
        'POST': {
            'skills': {
                secured: true,
                upload: true,
                geolocation: false,
                illustrations: true,
                schema: skillsSchema
            },
            'donations': {
                secured: true,
                upload: true,
                geolocation: true,
                illustrations: false,
                schema: donationsSchema
            }
        }
    },
}

接下来我应该返回吗?或下一个()?还是真的

function middleware(req, res, next) {
    const section = req.params[0]
    const method = req.method
    const { body } = req
    const {
        secured,
        upload,
        geolocation,
        illustrations,
        schema
    } = constraints[process.env.NODE_ENV][method][section];
    // Should I return next ? or next() ? or true
    const uploading = !upload ? next() : ops.multer
    const securing = !secured ? next() : ops.auth0
    const geoValid = !geolocation ? true : new PipeLine({
        point: {
            lat: body.lat,
            lng: body.lng
        }
    })
    .isPointInsidePolygon(coordinates)
    const undrawValid = !illustrations ? true : new PipeLine({
        body: body
    }).undrawSplit().joiValidate(schema).undrawJoin()
    res.locals.magicPipeLine = { geoValid, undrawValid }
    return [uploading, securing]
}

路线是:

router.post(/^\/(donations|skills|blogs)/,
  middleware,
  async (req, res, next) => {

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    您不能从中间件返回中间件,但可以返回一个中间件数组并使用扩展运算符。

    const items = [middleware1, middleware2, (req, res, next)=>{ next() }]
    
    app.get('/foo', ...items)
    

    您也可以从中间件调用中间件。

    1. 如果您的封装中间件调用next(),则不应调用它。如果您想将中间件集成到您的中间件中,您应该手动调用它,并将next 值发送给它(而不是调用它)。这是一个例子:Calling a middleware from within a middleware in NodeJS/ExpressJS

    2. 从中间件返回值根本不会影响流程。

    【讨论】:

    • 从中间件中调用中间件?这不是我想要的,在这里我只是想编写一个返回中间件数组的“函数”(正如 Express 所期望的那样)。这个函数本身,我不能在路由定义之外调用,因为它需要 reqres 本身,所以它也是一个中间件。
    • 这个函数,必须总是返回一个中间件数组(以某种方式配置,要么是下一个,要么是他们应该做的其他工作)
    • 它就像在运行时构建中间件,第一个中间件是我返回未来中间件(已配置)的函数。/
    • 那么答案是否定的。我会更新回复。
    • 我认为构建一个数组并传播它是最干净的选择。
    【解决方案2】:

    Express.js 中的中间件状态逻辑是关于按顺序处理请求和响应参数。

    您应该对请求参数(参数、查询、正文等)进行处理,然后将其分配给可以在 next() 函数中使用的命名空间。

    我最简单的授权流程是这样的。

    const authenticate = (roles) => (req, res, next) => {
      try {
        const { usr, rol, exp } = decode(req.headers.authorization, process.env.JWT_SECRET);
        if (exp > new Date().getTime()) {
          if (roles === 'all' || roles.includes(rol)) {
            req.user = usr;
            next();
          } else res.status(401).send('Wrong user type.');
        } else res.status(401).send('Expired token');
      } catch (e) { res.status(401).send('You need a token.'); }
    };
    

    如您所见,我正在使用“已处理”身份验证标头加载正文。

    你应该在你的中间件中返回 next()。

    【讨论】:

    • 我知道,但称它为“Pipeline()”而不是“middleware()”,从技术上讲,我可以返回[multer, auth0] 这是中间件吗?
    • 我用 multer 实现的唯一实现是在一个简单的 REST API 中将它与护照一起使用。 router.post('/', auth('all'), uploader.single('file'), upload.create.single); 如示例所示,据我所知,您可以向路由添加无限数量的中间件,为什么需要 [multer, auth0] 我真的不知道。
    猜你喜欢
    • 2011-12-07
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    相关资源
    最近更新 更多