我正在跟踪this question中的中间件链接示例。
我有一条路线app.put('/users/:id', isAuthenticated, (req, res) => {db.updateUser(req.params.id, req.body)}
。我正在尝试编写一个中间件函数,以验证URL中提供的ID是否与从包含在请求中的JWT检索到的ID匹配。
我已经有一个函数isAuthenticated
,它验证JWT并将res.locals.userId
设置为检索到的UID;因此我只想在这个新函数canModifyTarget
中使用它,但是由于某种原因,请求将永远挂起:
// This function works fine
isAuthenticated: function(req, res, next) {
let token;
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
token = req.headers.authorization.split(' ')[1];
admin.auth().verifyIdToken(token).then((decodedToken) => {
res.locals.userId = decodedToken.uid;
return next();
}).catch((error) => {
return res.status(HttpStatus.UNAUTHORIZED).send();
})
}
}
// Switching out isAuthenticated for this in the route causes a permanent hang
canModifyTarget: function(req, res, next) {
console.log('This is printed');
return (req, res, next) => {
console.log('This is NOT printed');
isAuthenticated(req, res, () => {
if (req.params.id === res.locals.userId) {
return next();
}
return res.status(HttpStatus.FORBIDDEN).send();
})
}
}
答案 0 :(得分:1)
中间件应该是一旦完成就调用“ next()”的回调函数。 您的第一个函数在执行时正在调用next()(最终,在您的诺言得到解决后)
您的第二个函数没有调用next(),它只是返回一个函数定义。
像这样定义它
let name = prompt('What's your name?');
并且如果isAuthenticated的第三个参数是回调,它应该可以工作
此外,您还应该在canModifyTarget: function(req, res, next) {
isAuthenticated(req, res, () => {
if (req.params.id === res.locals.userId) {
return next();
}
return res.status(HttpStatus.FORBIDDEN).send();
})
}
}
函数中定义一个“ else”用例,否则它也会挂起(可能会引发异常或其他情况?)
如果需要引用它们,请将它们存储在变量中,而不是直接在模块中定义它们。exports:
isAuthenticated
答案 1 :(得分:0)
我认为更简单的方法是将canModifyTarget
定义为另一种中间件。即:
function canModifyTarget(req, res, next) {
console.log('This is NOT printed');
if (req.params.id === res.locals.userId) {
return next();
}
return res.status(HttpStatus.FORBIDDEN).send();
}
,然后在isAuthenticated
中间件之后应用它:
app.put(
'/users/:id',
isAuthenticated,
canModifyTarget,
(req, res) => {db.updateUser(req.params.id, req.body)}
);
希望有帮助。