中间件可以在Express中返回中间件吗



我正在尝试将不同的中间件(这里是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
}
}
},
}

我下一步应该回来吗?还是next((?或true

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) => {

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

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

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

  1. 如果封装的中间件调用next(),则不应调用它。如果要将中间件集成到您的中间件中,则应手动调用中间件,并向其发送next值(不调用它(。这里有一个例子:从NodeJS/ExpressJS中的中间件中调用中间件

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

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

您应该处理请求参数(params、query、body等(,然后将其分配给可以在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((。

最新更新