我正在尝试将不同的中间件(这里是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)
您也可以从中间件调用中间件。
如果封装的中间件调用
next()
,则不应调用它。如果要将中间件集成到您的中间件中,则应手动调用中间件,并向其发送next
值(不调用它(。这里有一个例子:从NodeJS/ExpressJS中的中间件中调用中间件从中间件返回值根本不会影响流。
您应该处理请求参数(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((。