express-jwt同款UnauthorizedError错误,如何自定义抛出?
发布于 作者:苏南大叔 来源:程序如此灵动~
基于express,苏南大叔搭建了jwt令牌颁发及验证系统。在原本的单token的系统设定基础上,为了解决token丢失带来的安全问题,引入了双令牌策略。access_token访问率高,有效期短。而refresh_token使用率低,有效期长。基于这两个token的不同策略,苏南大叔又提出了令牌类型的属性设定。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:nodejs@20.18.0,express@4.21.2,jsonwebtoken@9.0.2,express-jwt@8.5.1。令牌属性设定并不是express-jwt原本就有的设定,所以,该中间件并不会抛出“令牌类型不匹配”的异常。本文就是为了解决这个问题,而做的准备。
令牌类型属性
令牌类型属性的设定的需求,苏南大叔是这么设想的:
- 在
access_token的payload里面,增加一个type为access的字段。并在相关接口的中间件verify过后,对其进行检测。 - 在
refresh_token的payload里面,增加一个type为refresh的字段。并在refresh接口的中间件verify过后,对其进行检测。

const options_access = {
secret: "sunan_access",
algorithms: ["HS256"],
};
let authCheckAccess = expressjwt(options_access);
app.get("/api/*", authCheckAccess, (req, res) => {
if (req.auth && req.auth.type === "access") {
// ...
}
});令牌鉴定相关异常
令牌verify的过程,可能会抛出很多异常。它们都属于UnauthorizedError,包括:
UnauthorizedError: No authorization token was foundUnauthorizedError: jwt malformedUnauthorizedError: The token has been revokedUnauthorizedError: jwt expiredUnauthorizedError: 令牌类型不匹配【本文新增类型】
一旦抛出异常,就从express-jwt这个中间件,转到全局的错误捕获中间件了,并不会运行对应路由的主体逻辑。而本文所提及的"令牌类型不匹配"的错误信息,类型归属上也应该属于UnauthorizedError。但是,并不是express-jwt原生就支持的情况。因此,这里引入了下面的代码逻辑:
app.get("/api/*", authCheckAccess, (req, res) => {
if (req.auth && req.auth.type === "access") {
// ...
}
else{
throw new Error("令牌类型不匹配");
}
});模拟抛出同款
为了填补错误类型不一致的问题,这里对上面的关键代码进行了修改。修改如下:
const { expressjwt, UnauthorizedError } = require("express-jwt");
//...
app.get("/api/*", authCheckAccess, (req, res) => {
if (req.auth && req.auth.type === "access") {
// ...
}
else{
// throw new Error("令牌类型不匹配");
throw new UnauthorizedError(401, Error("令牌类型不匹配"));
}
});核心代码:
new UnauthorizedError(401, Error("令牌类型不匹配"))这个代码看起来其实有些奇怪,不过确实是从express-jwt源码里面猜测的写法。
捕获修改错误
依然可以使用express放置在所有路由后面的自定义路由,来解决这个问题。express-jwt中间件以及自定义错误,都已经统一为了UnauthorizedError,所以也比较好进行统一处理了。
app.use((err, req, res, next) => {
if (err.name == "UnauthorizedError") {
return res.send({
status: -999,
message: err.message,
});
}
});
// app.listen(3222);
相关文章
- https://newsn.net/say/express-catch.html
- https://newsn.net/say/express-jwt.html
- https://newsn.net/say/express-json.html
- https://newsn.net/say/express.html