验证 Auth0 JWT 抛出无效算法

问题描述 投票:0回答:5

我已经创建了一个 Auth0 客户端,我正在登录并接收此令牌:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik1rVkdOa1l5T1VaQ1JqTkRSVE5EUmtNeU5rVkROMEUyUTBVMFJrVXdPVEZEUkVVNU5UQXpOZyJ9.eyJpc3MiOiJodHRwczovL3RvdGFsY29tbW56LmF1LmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDEwMzI5NzA4OTYyMTk5NjUwMjY2MiIsImF1ZCI6ImxTWUtXMUZZdENkMWJLQmdXRWN0MWpCbmtDU3R2dW5SIiwiaWF0IjoxNTA5ODYyMTI1LCJleHAiOjE1MTAyMjIxMjV9.kjmckPxLJ4H9R11XiBBxSNZEvQFVEIgAY_jj2LBy4sEJozBB8ujGE7sq9vEIjMms-Lv2q9WzFQPrqcxyBcYC4Je4QojMgvqLDCodtpot0QUle8QfGmonc1vZYIZyX-wqyOXtRqhoZVEKTeLhm9Le2CV4_a3BwgjkE1LjcDx01GZfsnaId8mh10kGk-DBmr5aVc8MxglLCq5Uk8Zbl2vDc__UMDgx1eQPQg-zve4fUf8zHcxizypYTnF_v0dEAT00L2j5J41SFYdWvP6ReQ3vhVYew2o9iM6u1s75HE-xW8s4pzV4BZAQtgfgIeCd6aVGZs76bcnQXBLej1B7zaPBvA

我现在想做的是使用 jsonwebtoken 验证令牌。该令牌使用 RS256 算法进行签名。

我将签名证书下载为

.pem
,并且我成功使用它来验证令牌,如下所示:

var cert = fs.readFileSync('certificate.pem');
jwt.verify(token, cert, {algorithm: 'RS256'}, (err, decoded) => {
  console.log(err)
  console.log(decoded)
});

我想做但不起作用的是使用密钥验证令牌(在 Auth0 客户端设置中称为 Client Secret 并且是一个字符串)。

jwt.verify(token, MYSECRET, {algorithm: 'RS256'}, (err, decoded) => {
  console.log(err)
  console.log(decoded)
});

此代码总是抛出错误:

{ JsonWebTokenError: invalid algorithm
    at Object.module.exports [as verify] (C:\code\aws\learn-authorizer\node_modules\jsonwebtoken\verify.js:90:17)
    at Object.<anonymous> (C:\code\aws\learn-authorizer\testme.js:25:5)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)
    at Function.Module.runMain (module.js:665:10)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3 name: 'JsonWebTokenError', message: 'invalid algorithm' }

我的问题是:如何使用密钥而不是使用证书文件来验证 RS256 令牌? (我也尝试创建一个使用 HS256 算法的新客户端,但我得到了同样的错误)。

node.js oauth jwt auth0 rs256
5个回答
14
投票

如果您仅使用密钥,则使用 RS256 将不起作用,因为它基于私钥/公钥对。仅使用密钥通常表示 H256。在我的回答中,我假设你所说的 MYSECRET 只是

certificate.pem
的内容。

无论如何,我假设你的字符串必须包含

-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----

PUBLIC

而不是 PRIVATE 您可以在

来源

中看到这一点。错误消息中提到的行包含: if (!~options.algorithms.indexOf(header.alg)) { return done(new JsonWebTokenError('invalid algorithm')); }

options.algorithms

定义为


if (!options.algorithms) { options.algorithms = ~secretOrPublicKey.toString().indexOf('BEGIN CERTIFICATE') || ~secretOrPublicKey.toString().indexOf('BEGIN PUBLIC KEY') ? [ 'RS256','RS384','RS512','ES256','ES384','ES512' ] : ~secretOrPublicKey.toString().indexOf('BEGIN RSA PUBLIC KEY') ? [ 'RS256','RS384','RS512' ] : [ 'HS256','HS384','HS512' ]; }

如果您在开始和结束时没有 RSA 东西,它将寻找以下算法:
'HS256','HS384','HS512'


我之前没有将RS256与JWT一起使用过,但我已经将其与ssh一起使用过,并且我知道它对具有标头非常敏感。该字符串的格式必须完全正确。


8
投票

algorithms

 指定为字符串数组,而不是 
algorithm 字符串。

jwt.verify(token, MYSECRET, { algorithms: ['RS256'] });



3
投票

{algorithm: 'RS256'} to ==>{algorithms: 'RS256'}

并确保为算法写下正确的名称,它会正常工作


2
投票

根据 Auth0 文档

https://auth0.com/docs/api-auth/tutorials/verify-access-token#verify-the-signature

For HS256, the API's Signing Secret is used. You can find this information at your API's Settings. Note that the field is only displayed for APIs that use HS256. For RS256, the tenant's JSON Web Key Set (JWKS) is used. Your tenant's JWKS is https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json.



0
投票

问题

decode 能够让我们了解 JWT
  • 但是我们需要验证令牌的签名
  • 以下代码中的
步骤

我们解码令牌(使用
    jsonwebtoken
  1. 我们从令牌中获取域名
  2. 我们使用该域获得具有众所周知/jwks 的 JSON 文件
  3. JWKS 可以不止一个,我们从 JWKS 获得相同的密钥,该密钥位于解码后的令牌标头中
  4. 我们使用
  5. node-jose
  6. 包来调用验证签名 您可以通过存储库在本地进行测试:
  7. https://github.com/AkberIqbal/auth0-jwt-verify-signature-javascript-nodejs

const verifyJWT = async (token, verifyURL) => { return new Promise(async (resolve, reject) => { const result = jwt.decode(token, { complete: true }); const domainFromToken = result?.payload?.iss; const signatureUrl = verifyURL ? verifyURL : `${domainFromToken}.well-known/jwks.json`; const jwksResponse = await axios.get(signatureUrl).catch((exp)=>{ console.log('Error getting jwkResponse:', exp); reject(false) }); const jwks = jwksResponse?.data?.keys; console.log('# of JWKS:', jwks.length, ' -trying to find:', result?.header?.kid); const relevantKey = jwks.filter(jk => jk.kid === result?.header?.kid)[0]; console.log('relevantKey:', relevantKey); const algoForImport = selectedKey.alg const publicKey = await jose.importJWK(relevantKey, algoForImport); const { payload, protectedHeader } = await jose.jwtVerify(token, publicKey, { iss: 'issuer, get this from decoded token, or the issuer you expect', }).catch(exp => { console.log('exp:', exp); reject(exp); }); if (payload && Object.keys(payload).length > 0) { console.log('Object.keys(payload):', Object.keys(payload)); // uncomment to take a closer look // console.log('joseResult:', joseResult); resolve('ok'); } }) }

© www.soinside.com 2019 - 2024. All rights reserved.