如果中间件在REST API中失败,会有什么反应



我正在读一段代码,它有两个文件,如下所示:

使用currentuser中间件的第一个文件:

const router = express.Router();
router.get("/api/users/currentuser", currentUser, (req, res) => {
res.send({ currentUser: req.currentUser || null });
});
export { router as currentUserRouter };

定义中间件的第二个文件:

interface UserPayload {
id: string;
email: string;
}
declare global {
namespace Express {
interface Request {
currentUser?: UserPayload;
}
}
}
export const currentUser = (
req: Request,
res: Response,
next: NextFunction
) => {
if (!req.session?.jwt) {
return next();
}
try {
const payload = jwt.verify(
req.session.jwt,
process.env.JWT_KEY!
) as UserPayload;
req.currentUser = payload;
} catch (err) {}
next();
};

我知道,如果有一个经过验证的jwt令牌,中间件将从中取出有效负载,并将其添加到req对象中。但是,如果它失败了,并且无法将有效负载/当前用户添加到req中,该怎么办?下面的请求会发生什么,res对象会是什么样子?

router.get("/api/users/currentuser", currentUser, (req, res) => {
res.send({ currentUser: req.currentUser || null });
});

你能编辑这个get请求吗?以显示如果我不是中间件的编写者,我如何捕捉可能的错误?

如果您有一个catchall异常处理程序,而您的中间件抛出了一个异常,那么您将确定响应。

如果您的中间件抛出了一个异常,而您没有捕捉到它,那么系统可能会退出该进程。

如果您的中间件没有抛出异常,也没有调用next((,也没有响应,那么请求将挂起。

如果您的中间件返回了响应,并且没有调用next((,那么您的send函数将永远不会被调用。

最重要的是,您需要将响应转储到服务器上,并查看中间件是如何处理的。

在我的大多数身份验证中间件中,我选择不调用next((,并返回403错误。但是抛出一个异常,然后从catchall处理程序返回403,也有一些好处。

您需要用错误HTTP状态代码和正文中的错误消息进行响应。确切的状态和消息取决于异常的类型及其参数,因此您需要捕获并检查它

当前的express中间件不处理错误,只是不设置req.currentUser = payload;,所以您不会了解用户。我认为这不是一个正确的身份验证错误解决方案。

在文档中,您可以看到如何处理错误:https://expressjs.com/en/guide/using-middleware.html

app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})

所以我会重写代码,如果JWT验证失败,那么我会返回例如401未经授权的代码。https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401

我猜您正在使用JWT库:https://github.com/auth0/node-jsonwebtoken根据文档和代码,有3种类型的错误:TokenExpiredError、JsonWebTokenError、NotBeforeError用于验证。在这里,您可以检查它们何时被抛出:https://github.com/auth0/node-jsonwebtoken/blob/master/verify.js,以下是它们的定义:https://github.com/auth0/node-jsonwebtoken/tree/master/lib

因此,在catch块中,您只需使用instanceof(例如if (err instanceof jwt.JsonWebTokenError) ...(检查错误的类型,然后使用res.status(401)相应地发送消息,并将next()放在try块的末尾,因为只有在验证没有失败的情况下才应该调用它。

最新更新