JWT 签发

填好载荷和密钥,立刻生成一个能过验签的 JWT。iat、exp、iss 这些声明可以自动补,也能手写覆盖。

签名的计算过程

JWT 由三段用点连接:头部、载荷、签名。头部说明算法,载荷放声明,前两段都是 Base64URL 编码的 JSON。签名不是对 JSON 原文算的,而是对 base64url(header) + "." + base64url(payload) 这一整串字符算 HMAC,所以服务端验签时也必须按同样的字符串拼接顺序来算,任何一处重新序列化(比如把键排序、把空格删掉)都会导致验签失败。

HS256 用 HMAC-SHA256,HS384、HS512 只是换了哈希函数,密钥长度和签名长度也跟着变。三者互不兼容:用 HS512 签的令牌拿 HS256 去验一定失败,这不是密钥问题,是算法不匹配。页面上选的算法会原样写进头部的 alg 字段,服务端一般也会校验这个字段,防止有人把算法改成 none 绕过验签。

时间声明

iat、exp、nbf 都是 Unix 秒级时间戳,不是毫秒。这一页在勾选后自动写入 iat,按选择的有效期算 exp;如果载荷里已经写了同名声明,就保留你写的值不覆盖,方便造一个「已经过期」或「还没生效」的令牌测边界。想确认某个令牌何时过期,用JWT 解析,它会把时间戳换算成本地时间并标出状态。

密钥怎么管

对称签发的前提是签发方和验签方共享同一个 secret。这个 secret 一旦泄露,任何人都能伪造令牌,所以线上环境应该用足够长的随机串(至少 32 字节),放在服务端的环境变量或密钥管理服务里,不要提交到仓库,也不要在前端代码里出现。但页面本身是公开的,公共电脑上不要填真实密钥。需要生成随机密钥可以用随机密码生成或者RSA 密钥对生成改用非对称方案。

常见问题

为什么只支持 HS256、HS384、HS512?

这三个是对称算法,签名和验签用同一个 secret,浏览器里用 WebCrypto 直接算就行。RS256、ES256 需要导入私钥,私钥格式(PKCS#8、JWK)千差万别,还容易把真实私钥贴进网页,所以这里不做。要在本地生成 RSA 密钥对,用 RSA 密钥对生成。

相关:RSA 密钥对生成

生成的令牌能直接拿去调接口吗?

可以,前提是目标服务端配的 secret 和这里填的完全一致,并且算法也对得上(HS256 的令牌不能被 HS512 验过)。令牌里写的是签发时间,服务端如果校验 exp,过期后就会拒绝。

公共电脑上能用吗?

不建议。密钥只存在于当前页面的内存中,刷新页面就没了;但公共电脑上的浏览器扩展和旁人都可能看到,真实密钥不要在这种环境里使用。

exp 和 iat 填的是秒还是毫秒?

秒。JWT 规范里 exp、nbf、iat 都是 Unix 时间戳,单位是秒。这一页在勾选「自动写入 iat」和选择有效期后自动填好,也可以自己在载荷里写死覆盖它。

载荷里已经有 exp,还会被覆盖吗?

不会。页面只在载荷里没有同名声明时才自动补 iat、exp、iss、sub、aud,已经写了的以你填的为准,这样方便造一个指定过期时间的令牌来测边界情况。

签名结果怎么验证?

把令牌发给服务端,用同一个 secret 和算法验签即可;也可以在本地用 HMAC 工具对「头部.载荷」这段字符串算一次 HMAC-SHA256,再把结果转成 Base64URL 对照。只想看令牌里写了什么,用 JWT 解析。

相关:JWT 解析HMAC 与密钥派生