我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

基于express,苏南大叔搭建了jwt令牌颁发及验证系统。在原本的单token的系统设定基础上,为了解决token丢失带来的安全问题,引入了双令牌策略。access_token访问率高,有效期短。而refresh_token使用率低,有效期长。基于这两个token的不同策略,苏南大叔又提出了令牌类型的属性设定。

苏南大叔:express-jwt同款UnauthorizedError错误,如何自定义抛出? - express-jwt-同款unauthorizederror
express-jwt同款UnauthorizedError错误,如何自定义抛出?(图3-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:nodejs@20.18.0,express@4.21.2jsonwebtoken@9.0.2express-jwt@8.5.1。令牌属性设定并不是express-jwt原本就有的设定,所以,该中间件并不会抛出“令牌类型不匹配”的异常。本文就是为了解决这个问题,而做的准备。

令牌类型属性

令牌类型属性的设定的需求,苏南大叔是这么设想的:

  • access_tokenpayload里面,增加一个typeaccess的字段。并在相关接口的中间件verify过后,对其进行检测。
  • refresh_tokenpayload里面,增加一个typerefresh的字段。并在refresh接口的中间件verify过后,对其进行检测。

苏南大叔:express-jwt同款UnauthorizedError错误,如何自定义抛出? - payload增加字段
express-jwt同款UnauthorizedError错误,如何自定义抛出?(图3-2)

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);

苏南大叔:express-jwt同款UnauthorizedError错误,如何自定义抛出? - 错误代码全控制
express-jwt同款UnauthorizedError错误,如何自定义抛出?(图3-3)

相关文章

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   express    jwt