API 联调排错
后端返回的 JWT 在客户端登录失败,前端抓包发现 token 能解码但签名校验不通过。用本工具分别粘贴 header、payload 和 signature,逐段对比 base64 编码后的内容是否与预期一致,快速定位到是 payload 中多了一个空格导致签名不匹配,省去逐行读源码的排查时间。
编码加密 · JWT / Token
header/payload/signature/校验
调试 OAuth 登录或 API 鉴权时,最怕手写 token 验证逻辑,却因 signature 对不上卡住。输入 JWT 字符串,它自动拆解 header、payload、signature 三段,并允许用密钥或公钥现场校验签名是否一致。解析与校验全在浏览器内完成,不向服务器发送 token 内容——适合本地开发调试或安全审计时快速验签。
后端返回的 JWT 在客户端登录失败,前端抓包发现 token 能解码但签名校验不通过。用本工具分别粘贴 header、payload 和 signature,逐段对比 base64 编码后的内容是否与预期一致,快速定位到是 payload 中多了一个空格导致签名不匹配,省去逐行读源码的排查时间。
接入微信开放平台时,对方文档只给了示例 JWT 和签名算法,没有在线调试环境。把示例 token 粘贴进本工具,逐段解析 header 中的 alg 字段、payload 中的 openid 和 exp,再用自己的 secret 重新签名对比,确认签名逻辑无误后再写代码,避免因算法理解偏差导致线上认证失败。
QA 需要一批不同过期时间的 JWT 来测试自动续签逻辑。手动构造 base64 太容易写错 exp 时间戳格式。用本工具直接修改 payload 中的 exp 字段为指定 Unix 时间戳,工具自动重新计算签名,生成有效 token,一次性造出过期、即将过期、有效三种状态的测试用例,比手写脚本快得多。
安全团队扫描发现某老系统还在用 'alg: none' 的 JWT。把可疑 token 粘贴进本工具,工具直接显示 header 中 alg 字段为 'none',且 payload 任意修改后签名校验仍通过。截图作为漏洞报告附件,推动开发组升级到 RS256 算法,并验证新 token 的签名密钥强度是否达标。
单点登录页面在本地开发环境下拿到的 JWT 总在跳转后失效。用本工具解析 token,发现 payload 中的 aud(受众)字段写的是生产域名,本地 localhost 不匹配导致认证服务拒绝。修改 aud 为本地地址后重新生成 token,前端立即能正常跳转,定位耗时从半小时缩短到 2 分钟。
| 输入 | 输出 | 说明 |
|---|---|---|
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c | Header: {"alg":"HS256","typ":"JWT"} Payload: {"sub":"1234567890","name":"John Doe","iat":1516239022} Signature: SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 验证结果:签名有效(需提供密钥) | 常规:RFC 7519 标准示例 JWT,验证基本解码与签名校验流程 |
| eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJleHAiOjE3MDAwMDAwMDB9 | Header: {"alg":"RS256","typ":"JWT"} Payload: {"iss":"https://auth.example.com","exp":1700000000} Signature: 缺失(仅两段) | 边界:缺少 signature 段的 JWT(仅 header.payload),工具应提示格式不完整 |
| eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9. | Header: {"alg":"none"} Payload: {"data":"test"} Signature: 空 验证结果:alg=none 无签名,安全风险 | 易错:alg=none 的 JWT,工具应明确警告无签名带来的安全风险 |
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0Iiwicm9sZSI6ImFkbWluIn0.abc123 | Header: {"alg":"HS256","typ":"JWT"} Payload: {"sub":"test","role":"admin"} Signature: abc123 验证结果:签名无效(密钥不匹配或签名被篡改) | 易错:签名段为随意字符串,工具应正确识别签名无效,而非报解析错误 |
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOi0xfQ.invalid_base64!! | Header: {"alg":"HS256","typ":"JWT"} Payload: {"exp":-1} Signature: 解析失败(非法 Base64 字符) | 边界:signature 段包含非法 Base64 字符,工具应输出具体错误而非崩溃 |
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiLmtY/op4jml6Dms5UiLCJpYXQiOjE2MDAwMDAwMDB9.xxx | Header: {"alg":"HS256","typ":"JWT"} Payload: {"sub":"中文用户","iat":1600000000} Signature: xxx 验证结果:签名无效 | 常规:包含中文的 payload,验证工具对 UTF-8 编码的支持 |
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjpudWxsLCJiIjp0cnVlLCJjIjoxMjMuNDV9.xxx | Header: {"alg":"HS256","typ":"JWT"} Payload: {"a":null,"b":true,"c":123.45} Signature: xxx 验证结果:签名无效 | 边界:payload 包含 null、布尔值、浮点数等 JSON 类型,验证工具解析的健壮性 |
1.Payload 里直接写 JavaScript 对象,未 JSON 序列化
{
sub: "1234567890",
name: "John Doe",
admin: true
}{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}JWT 的 payload 必须是合法 JSON 字符串,键名必须用双引号包裹。直接写对象字面量会导致解析失败或签名校验不通过(RFC 7519 要求 JSON 序列化)。
2.Secret 里包含空格或换行,签名结果不一致
my secret keymy_secret_keyHMAC 签名是对字节的精确运算,末尾空格或换行会被作为签名输入的一部分,导致相同 payload 在不同工具或语言中签名结果不同。
3.Header 里 alg 写错或大小写错误
{
"alg": "hs256",
"typ": "JWT"
}{
"alg": "HS256",
"typ": "JWT"
}JWT 标准(RFC 7518)定义的算法名全大写:HS256、RS256、ES256 等。小写或混写会被解析器视为未知算法,导致签名验证失败。
4.Payload 里包含 undefined 或 NaN 等非 JSON 值
{
"exp": NaN,
"iat": undefined
}{
"exp": 1700000000,
"iat": 1699990000
}JSON 标准不支持 NaN、undefined、Infinity 等值。序列化时这些值会被忽略或转为 null,导致 payload 结构变化,影响签名一致性。
5.Signature 段复制时遗漏了末尾的 Base64URL 填充符
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dQw4w9WgXcQeyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dQw4w9WgXcQ=JWT 使用 Base64URL 编码(无填充),但某些工具或库在解码时仍期望填充符。若签名段末尾缺少 '=',解码可能失败或产生不同字节,导致校验不通过。
6.过期时间 exp 用了字符串而非 Unix 时间戳
{
"exp": "2025-01-01T00:00:00Z"
}{
"exp": 1735689600
}JWT 标准(RFC 7519)规定 exp、iat、nbf 等时间字段必须为 NumericDate(Unix 时间戳整数)。字符串日期会被多数解析器忽略或报错,导致过期校验失效。
7.复制 JWT 时包含了多余的空格或换行
eyJhbGciOiJIUzI1NiJ9. eyJzdWIiOiIxMjM0NTY3ODkwIn0. dQw4w9WgXcQ=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dQw4w9WgXcQ=JWT 是一个紧凑的字符串,三个部分之间没有空格。任何空白字符都会破坏整体结构,导致解析器无法正确分割 header、payload 和 signature。
8.用 RSA 签名时,公钥和私钥搞混
用私钥去验证签名私钥签名,公钥验证RSA 非对称算法中,私钥用于生成签名,公钥用于验证签名。用私钥验证或公钥签名都会导致校验失败,且可能暴露私钥安全风险。
signature = HMAC-SHA256( base64url(header) || '.' || base64url(payload), secret )
headerJWT 头部 JSON,含算法和类型payloadJWT 载荷 JSON,含声明数据secretHMAC 密钥,服务端保管的字符串base64urlBase64 URL 安全编码,去填充符signature签名输出,用于验证完整性header = {"alg":"HS256","typ":"JWT"} → base64url 得 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9;payload = {"sub":"1234567890","name":"John Doe","iat":1516239022} → base64url 得 eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ;拼接 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ 作为输入,密钥 secret = "your-256-bit-secret",HMAC-SHA256 计算得签名二进制,再 base64url 得最终签名值(如 SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c)。
payload 部分理论上可以放任意 JSON 对象,但实际有大小限制。本工具纯前端处理,不限制字符数,但浏览器内存和 URL 传输场景下,JWT 总长度超过 8KB 就可能被部分 Web 服务器或网关拒绝。另外 payload 里放敏感信息(如密码明文)是不安全的——JWT 的 payload 只是 Base64 编码,不是加密,任何人都能解码看到内容。
签名不一样最常见的原因是 secret(密钥)不一致。其次是 header 里 alg 字段不同——比如一个用 HS256,另一个用 HS384,即使密钥内容相同,签名算法不同结果也不同。另外,本工具在编码时对 JSON 做了紧凑序列化(去掉空格和换行),如果你在别处用的是格式化后的 JSON,字节不同,签名自然不同。可以先把 header 和 payload 分别用 JSON.stringify 压缩后再比对。
本工具校验时会用你输入的 secret 重新计算签名,然后跟 token 里的签名段比对。校验失败最常见的原因是 secret 输错了。其次,如果 token 过期(payload 里有 exp 字段且时间已过),工具会提示过期而非签名错误。还有一种情况:token 是用 RSA 等非对称算法签名的,但你在校验时只提供了对称密钥(secret),这时必须提供对应的公钥才能校验。
能,但需要正确提供公钥。本工具支持 HS256/384/512 和 RS256/384/512 等常见算法。使用 RS256 时,校验步骤里不能填对称密钥 secret,而应粘贴 PEM 格式的公钥(以 -----BEGIN PUBLIC KEY----- 开头)。注意公钥和签名的算法必须匹配——RS256 的签名不能用 HS256 的公钥校验,会直接报错。
iat(签发时间)和 exp(过期时间)的值必须是 Unix 时间戳,单位是秒,不是毫秒。常见的坑:用 JavaScript 的 Date.now() 得到的是毫秒,直接填进去会导致过期时间比预期晚 1000 倍。正确做法是 Math.floor(Date.now() / 1000) 得到秒。本工具的解码结果区会自动把时间戳转成可读日期,方便你确认填对了没有。
完全纯前端,所有编解码和签名校验都在浏览器里完成,不会向任何服务器发送数据。你可以断网测试:关闭网络后刷新页面,工具依然可以正常使用。这对处理包含敏感信息的 JWT 特别重要——比如你在调试包含用户 ID 或权限数据的 token 时,不用担心数据经过第三方服务器。
JWT 的 payload 要求是 UTF-8 编码的 JSON,但如果你在生成时放了非 UTF-8 的字符(比如 GBK 编码的中文),或者 payload 里直接塞了二进制数据(如图片的 Base64),解码后就会显示乱码。本工具默认按 UTF-8 解码,如果出现乱码,可以检查生成时是否用了正确的字符编码。另外,payload 里如果有特殊转义字符(如 \uXXXX),解码后会自动转成对应 Unicode 字符,看起来可能和原始输入不同,但语义一致。
可以加,比如 kid(密钥 ID)、jku(JWK Set URL)、cty(内容类型)等。这些额外字段不会被校验算法本身处理,但会被解码后完整显示。加自定义字段不会导致解码失败,但需要注意:如果加了 jku 这类指向外部 URL 的字段,在安全场景下应该验证该 URL 是否可信,否则可能被用于 JWT 注入攻击。本工具会原样展示所有 header 字段,不进行额外验证。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。