jwt.io 中总是收到无效签名

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

当我在 jwt.io 中输入生成的令牌时,总是得到无效签名 这是我制作令牌的代码

const secret = 'secret';
const token = jwt.sign({
    username: user.username,
    userID: user._id
  },
  secret, {
    expiresIn: "1hr"
  }
);

我做错了什么?

我正在使用 jsonwebtoken 包。 https://github.com/auth0/node-jsonwebtoken

node.js jwt jwt.io
6个回答
34
投票

TL_DR:

keys
返回的 JSON 中的
https://example.com/.well-known/jwks
数组中提取第一个键,并将其粘贴到 jwt.io 页面
VERIFY SIGNATURE
部分的第一个文本框中。当然,
example.com
是您托管 OpenIddict 身份验证服务器的域。也可能是类似
https://example.com/my/auth/server/
的东西。

整个故事:

当您将 JWT 粘贴到 jwt.io 中时,它会执行以下操作:

  1. 解码令牌,并在右侧显示标头和有效负载
  2. 尝试验证签名

如果步骤 1. 无法解码有效负载,那是因为令牌已被编码。要解决此问题,请修改 OpenIddict 配置,添加

.DisableAccessTokenEncryption();

第 2 步,签名验证,是通过从

iss
部分获取颁发者
PAYLOAD
字段来完成的:

并使用它作为基本 URI 来调用

/.well-known/openid-configuration
,其中包括 JWKS uri,看起来像
"jwks_uri": "https://example.com/.well-known/jwks"

jwt.io 可能无法获取此数据,例如:

  • 如果您在无法通过互联网访问的
    https://localhost
    中进行测试,就像本示例中的
    https://localhost:5001
  • 因为请求被任何其他原因拒绝(未知域、防火墙...)

如果是这种情况,有一个选项可以解决该问题:将适当的字符串粘贴到

VERIFY SIGNATURE
部分的上部文本框中,其中包含以下占位符:

SPKI、PKCS #1、X.509 证书或 JWK 字符串格式的公钥。

粘贴到那里的正确字符串是什么?如果您考虑到 2 个细节,那就很容易了:

  1. 您可以从上述
    https://example.com/.well-known/jwks
    端点获取包含此信息的JSON
  2. 返回的信息是JWKS字符串,但需要JWK。

因此,调用 enpoint,获取 JWKS,如下所示:

{
  "keys": [
    {
      "kid": "2727AC6EB83977...",
      "use": "sig",
      "kty": "RSA",
      "alg": "RS256",
      "e": "AQAB",
      "n": "6tSSW3rz53Xj3w...",
      "x5t": "Jyesbrg5d_2M...",
      "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
      ]
    }
  ]
}

并提取 JWK,它只是

"keys"
数组中的第一个条目,即

{
  "kid": "2727AC6EB83977...",
  "use": "sig",
  "kty": "RSA",
  "alg": "RS256",
  "e": "AQAB",
  "n": "6tSSW3rz53Xj3w...",
  "x5t": "Jyesbrg5d_2M...",
  "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
   ]
}

将此值粘贴到文本框中,您将收到蓝色的“签名已验证”消息,如第一个快照底部所示。

注意:根据配置(

AddEphemeralSigningKey()
AddDevelopmentSigningCertificate()
等),JWKS 键可以具有更多或更少的属性,但无论如何它都应该可以工作。


20
投票

如果您使用 jsonwebtoken lib,我尝试并能够创建令牌并进行验证。请查看代码,如果您仍然遇到问题,请在评论中告诉我。

var jwt = require('jsonwebtoken')

const secret = 'secret';
const token = jwt.sign({
        username: "",
        userID: 1
    },
    secret, {
        expiresIn: "1hr"
    },
    function(err, token) {
        if (err) {
            console.log(err);
        } else {
            console.log(token);
        }
    });

这是 jwt.io 的链接,我在其中输入了您使用的秘密,并且显示已验证。

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vyb mFtZSI6IiIsInVzZXJJRCI6MSwiaWF0IjoxNTI4NTUyMDYyLCJleHAiOjE1Mjg1NTU2NjJ9.raL79zTGON yXgr9vuXzAyMflHJ0JqPYTXsy9KwmlXhA


5
投票

就我而言,我忘记将密钥放入“验证签名”(右侧,“标头”和“有效负载”框之后)。截至 2023 年 5 月,jwt.io 中的空密钥在检查其令牌验证时不会向用户显示任何错误 - 大多数用户都会收到此错误

Invalid Signature
。确保将密钥字符串放在:

之后

HMACSHA256( base64UrlEncode(标头)+“。” + base64UrlEncode(有效负载),在此处输入您的密钥

智威汤逊.IO


0
投票

我也遇到过类似的问题,后来我发现我使用了错误的秘密

确保您使用正确的秘密


0
投票

就我而言,jwt.io 无法检索我的公钥(如上所述上文),因为我的服务器没有返回 CORS 标头以允许 jwt.io 等前端 JavaScript 应用程序访问正确的端点。


-1
投票

我也有同样的问题。我修复了它或在单击

中的“秘密 Base64 编码”复选框后进行了验证
© www.soinside.com 2019 - 2024. All rights reserved.