You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用express-jwt返回非401的自定义状态码?

解决express-jwt可选认证场景下令牌过期返回自定义状态码的问题

要实现可选认证(credentialsRequired: false)时,令牌存在但过期返回402状态码的需求,你需要在express-jwt的中间件之后添加一个自定义的错误处理中间件——因为当credentialsRequired: false时,express-jwt不会主动抛出错误,而是将验证失败的信息存储在req.authInfo中。

步骤1:保留原有的express-jwt配置

你的decodeAuthIfExist配置不需要修改,保持原样即可:

const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa'); // 确保已引入依赖

exports.decodeAuthIfExist = jwt({
  secret: jwksRsa.expressJwtSecret({
    cache: true,
    rateLimit: true,
    jwksRequestsPerMinute: 5,
    jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
  }),
  credentialsRequired: false,
  audience: process.env.AUTH0_AUDIENCE,
  issuer: `https://${process.env.AUTH0_DOMAIN}/`,
  algorithms: ['RS256']
});

步骤2:添加自定义错误处理中间件

创建一个中间件来检查req.authInfo中的错误信息,针对令牌过期的情况返回402状态码:

exports.handleOptionalAuthError = (req, res, next) => {
  // 检查是否存在认证错误
  if (req.authInfo) {
    // 判断是否为令牌过期错误
    if (req.authInfo.name === 'TokenExpiredError') {
      return res.status(402).json({
        error: 'TokenExpired',
        message: '你的认证令牌已过期,若需要请重新获取'
      });
    }
    // 你也可以扩展处理其他令牌错误,比如无效签名
    // else if (req.authInfo.name === 'JsonWebTokenError') {
    //   return res.status(400).json({ error: 'InvalidToken', message: '无效的认证令牌' });
    // }
  }
  // 没有错误则继续执行后续中间件
  next();
};

步骤3:在路由中组合使用中间件

将自定义错误处理中间件放在decodeAuthIfExist之后,确保能捕获到认证错误:

app.get('/resource', auth.decodeAuthIfExist, auth.handleOptionalAuthError, resource.get);

原理说明

当credentialsRequired: false时:

  • 如果请求中没有令牌,express-jwt不会做任何处理,直接进入下一个中间件
  • 如果请求中有令牌但验证失败(比如过期、签名错误),express-jwt会将错误信息存入req.authInfo,而不会抛出默认的401错误
  • 我们的自定义中间件通过检查req.authInfo,识别令牌过期的错误类型,返回自定义的402状态码,避免应用自动跳转到登录页

内容的提问来源于stack exchange,提问作者kane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:42:18