NodeJS/ExpressJS中jwt.verify()报错error:1E08010C求助
JWT验证报错:error:1E08010C:DECODER routines::unsupported
错误详情
Error: error:1E08010C:DECODER routines::unsupported at Verify.verify (node:internal/crypto/sig:230:24) at Object.verify (.../node_modules/jwa/index.js:164:21) at Object.jwsVerify [as verify] (.../node_modules/jws/lib/verify-stream.js:54:15) at .../node_modules/jsonwebtoken/verify.js:127:19 at getSecret (.../node_modules/jsonwebtoken/verify.js:90:14) at module.exports [as verify] (.../node_modules/jsonwebtoken/verify.js:94:10) at exports.verify (.../middleware.js:30:17) at Layer.handle [as handle_request] (.../node_modules/express/lib/router/layer.js:95:5) at next (.../node_modules/express/lib/router/route.js:137:13) at Route.dispatch (.../node_modules/express/lib/router/route.js:112:3) { library: 'DECODER routines', reason: 'unsupported', code: 'ERR_OSSL_UNSUPPORTED' }
已尝试的无效方案
- 更换Node.js v16、v18、v20版本
- 启动脚本添加
--openssl-legacy-provider参数并配置环境变量 - 将M1机器的OpenSSL更新至3.2.1版本
- 将公钥编码为Base64字符串
当前代码:
exports.verify = async (req, res, next) => { const publicKey = `-----BEGIN PUBLIC KEY-----///-----END PUBLIC KEY-----` const accessToken = req.headers.authorization.split(" ")[1] if(!accessToken) res.sendStatus(403).json({ error: "please provide a token" }) else { try { jwt.verify( accessToken, publicKey, { algorithms: ['RS256'] }, (err, decoded) => {if(err) { console.log(err) } else { resolve(decoded) next() }} ) } catch(err) { console.log(err) } } }
此前代码正常运行,仅更换Auth服务公钥及Token签发方后出现问题。
核心原因分析
从代码和报错信息来看,最可能的触发点是:
- 新公钥格式不合法:代码中用
///作为占位符,实际使用的公钥可能缺失完整PEM结构、换行符,或内容损坏 - 算法不匹配:新Auth服务签发Token的算法与代码指定的
RS256不一致 - Token无效:使用的仍是旧Auth服务签发的Token,与新公钥不匹配
针对性解决方案
1. 修复公钥格式
确保公钥是完整的PEM格式:
- 必须包含
-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----首尾标记 - 中间的公钥内容需正确换行,每行约64字符(不要压缩成一行,也不要有多余空格/特殊字符)
- 直接从新Auth服务的官方渠道获取公钥(如JWKS端点、控制台导出),禁止手动修改或截断
2. 验证算法与Token匹配
- 确认新Auth服务签发Token使用的算法确实是
RS256,若为其他算法(如RS384/ES256),需同步修改代码中的algorithms参数 - 用JWT解析工具验证Token签名有效性(输入Token和正确公钥,确认签名通过)
3. 修正代码逻辑问题
- 移除不必要的
async关键字(jwt.verify回调版本无需Promise) - 完善请求头校验:检查
authorization是否存在且以Bearer开头,避免split报错 - 发送响应后需
return,防止后续代码执行 - 移除错误的
resolve调用(回调版本无需Promise resolve)
修正后的代码示例
exports.verify = (req, res, next) => { // 替换为新Auth服务提供的完整、正确格式的公钥 const publicKey = `-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxQexamplePublicKeyContent examplePublicKeyContentexamplePublicKeyContentexamplePublicKeyContent examplePublicKeyContentexamplePublicKeyContentexamplePublicKeyContent -----END PUBLIC KEY-----`; const authHeader = req.headers.authorization; // 严格校验请求头格式 if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(403).json({ error: "please provide a valid Bearer token" }); } const accessToken = authHeader.split(" ")[1]; jwt.verify( accessToken, publicKey, { algorithms: ['RS256'] }, // 确保与Auth服务算法一致 (err, decoded) => { if (err) { console.error('JWT验证失败:', err); return res.status(401).json({ error: "Invalid or expired token" }); } // 将解析后的用户信息挂载到req对象,供后续路由使用 req.user = decoded; next(); } ); };
内容的提问来源于stack exchange,提问作者fedjedmedjed
相关产品推荐
相关产品推荐

