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 found
UnauthorizedError: jwt malformed
UnauthorizedError: The token has been revoked
UnauthorizedError: jwt expired
UnauthorizedError: 令牌类型不匹配
【本文新增类型】
一旦抛出异常,就从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
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。