错误信息
secret or public key must be provided
也可能输出为
- secretOrPrivateKey must have a value
`jwt.sign()` 会把同样的问题报告为“secretOrPrivateKey must have a value”(普通的 `Error`)。
jsonwebtoken (Node.js) — JsonWebTokenError from jwt.verify(); the sign() twin is a plain Error
含义
`jwt.verify()` 收到了已签名的令牌,但密钥参数为空(`undefined`、`null` 或 `""`)。没有密钥,jsonwebtoken 就无法检查签名,所以它在查看令牌之前就停止了。签名一侧有一个对应的错误 `secretOrPrivateKey must have a value`,出于同样的原因由 `jwt.sign()` 抛出。
原因
当前环境没有设置该环境变量
常见`process.env.JWT_SECRET` 或 `JWT_PUBLIC_KEY` 在开发者的机器上存在,但在容器、CI 任务或无服务器函数中不存在。平台控制台通常按环境(预览与生产)分别设置变量的作用范围。
.env 在读取该值之后才加载
常见如果 `dotenv` 在入口文件中较晚才配置,在导入时读取 `process.env.JWT_SECRET` 的模块拿到的就是 `undefined`。使用 ES 模块时,被导入的模块会在导入它们的文件的代码运行之前求值。
密钥回调没有返回任何密钥
偶见使用 `getKey(header, callback)` 函数时(例如基于 jwks-rsa 实现),如果因为查找没有返回密钥而调用了 `callback(null, undefined)`,得到的就是这个错误,而不是“找不到密钥”的错误。
修复方法
- 1.
在启动时校验配置
在进程启动时一次性读取所需的密钥,缺少任何一个就输出明确的消息并退出。这样配置错误的实例永远不会开始处理请求。
js function requireEnv(name) { const value = process.env[name]; if (!value) throw new Error(name + " is not set"); return value; } const JWT_PUBLIC_KEY = requireEnv("JWT_PUBLIC_KEY"); // evaluated once at startup - 2.
最先加载环境变量文件
把 `dotenv/config` 作为第一个导入,或者使用 Node 内置的 `--env-file` 参数,让每个模块都能读到这些值。
js // Load .env before any module that reads process.env at import time. import "dotenv/config"; import { app } from "./app.js"; // Node 20.6+: no package needed // node --env-file=.env server.js