使用jsonwebtoken生成ES256算法JWT令牌却得到HS256的问题
问题根因定位
你遇到的问题来自两个层面的配置错误,具体如下:
第一处错误:参数传参位置不符合jsonwebtoken方法签名
jsonwebtoken库的sign方法固定参数结构为:jwt.sign(payload, secretOrPrivateKey, [options, callback])
其中:
- 第三个参数是承载所有可选配置的对象,过期时间、指定算法的配置都需要放在这个对象内
- 第四个参数是异步调用时的回调函数位置,传入的任何非函数值都不会被解析为方法配置
你当前的代码把{ algorithm: 'ES256' }错放到了第四个参数的位置,相当于传给方法的配置对象里只有expiresIn: '24h',根本没有声明自定义算法,方法就会使用默认的HS256生成令牌,这是你生成的令牌和预期不符的直接原因。
第二处错误:算法与密钥类型不匹配
即使把algorithm配置挪到正确的位置,当前传入的普通字符串密钥'testsecret'也无法支持ES256算法:
- ES256是基于椭圆曲线的非对称签名算法,要求传入的密钥必须是符合PEM编码格式的secp256r1曲线ECDSA私钥;如果强行用普通字符串搭配ES256配置,方法会直接抛出私钥格式校验错误,无法正常生成令牌。
- 普通字符串形式的密钥仅能搭配HS系列的对称签名算法(HS256/HS384/HS512)使用。
正确的实现示例
如果要使用ES256算法生成令牌,需要先本地生成对应曲线的ECDSA密钥对,再将所有配置合并到第三个参数的options对象中,示例代码如下:
const jwt = require('jsonwebtoken') const fs = require('fs') // 读取本地生成的ECDSA私钥(PEM格式) const ecPrivateKey = fs.readFileSync('./ec256-private-key.pem') const accessToken = jwt.sign( { name: 'John' }, ecPrivateKey, { expiresIn: '24h', algorithm: 'ES256' } ) console.log(accessToken)
如果你的场景本来就打算用对称密钥生成令牌,只是想调整对称算法的强度,正确的写法是将所有配置合并到同一个options对象:
const jwt = require('jsonwebtoken') const accessToken = jwt.sign( { name: 'John' }, 'testsecret', { expiresIn: '24h', algorithm: 'HS512' // 对称场景下此处写HS系列算法可正常生效 } ) console.log(accessToken)
内容的提问来源于stack exchange,提问作者Daryl Wong
相关产品推荐
相关产品推荐

