关于 jwt-validate
jwt-validate 是用于检查 JWT 结构、声明和签名的安全技能。它在首次验证失败时停止,并要求签名验证使用预期算法及用户提供的密钥材料。
主要功能
- 01检查 JWT 结构与 JSON
- 02验证过期时间及时间声明
- 03按需匹配签发者、受众和主题
- 04使用密钥、PEM 公钥或 JWKS 验签
- 05限制算法并安全处理密钥
适用场景
- 01检查 JWT 是否过期或尚未生效
- 02将签发者、受众或主题与预期值比对
- 03使用提供的密钥验证令牌
- 04检查令牌并明确标注未验证的签名
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jsonwebtoken/ jwt-skills --skill jwt-validate安装后在 Claude Code 中输入/jwt-validate确认已加载。
详细介绍
JWT 验证
验证 JWT 的签名并校验其声明。确认令牌真实有效、尚未过期且结构正确。
验证顺序
按以下顺序检查。遇到第一个失败项时停止并报告。
1. 结构
- 必须恰好包含 3 个以点分隔的部分,且每部分都是有效的 base64url
- Header 和 payload 必须能解析为有效的 JSON
- Header 必须包含
alg;alg不能是none(除非明确预期如此)
2. 声明
exp必须是未来时间(报告距过期还有多久,或已过期多久)nbf必须是过去或当前时间iat必须是过去时间;如果超过 30 天,则标记出来iss、aud、sub— 如果用户提供了预期值,则必须匹配- 所有时间检查均允许 60 秒的时钟偏差
3. 签名
用户必须提供密钥、PEM 公钥或 JWKS URI。始终通过内联环境变量传递密钥和令牌,避免其暴露在 shell 历史记录中。
Node.js(首选):
首先,确保 jose 可用 — 如果缺失,则全局安装:
node --input-type=module -e "await import('jose')" 2>/dev/null || npm install -g jose
然后验证令牌:
JWT_TOKEN='the.jwt.here' JWT_SECRET='user-provided-secret' node --input-type=module -e "import {jwtVerify} from 'jose'; try { const {payload}=await jwtVerify(process.env.JWT_TOKEN, new TextEncoder().encode(process.env.JWT_SECRET), {algorithms:['HS256'],clockTolerance:60}); console.log('VALID'); console.log(JSON.stringify(payload,null,2)); } catch(e) { console.log('INVALID:',e.message); }"
Python:
JWT_TOKEN='the.jwt.here' JWT_SECRET='user-provided-secret' python3 -c "
import jwt,json,os
try:
d=jwt.decode(os.environ['JWT_TOKEN'],os.environ['JWT_SECRET'],algorithms=['HS256'],leeway=60)
print('VALID'); print(json.dumps(d,indent=2))
except Exception as e: print(f'INVALID: {e}')
"
JWKS 验证(Node.js):
JWT_TOKEN='the.jwt.here' JWKS_URI='https://example.auth0.com/.well-known/jwks.json' node --input-type=module -e "import {jwtVerify,createRemoteJWKSet} from 'jose'; try { const {payload}=await jwtVerify(process.env.JWT_TOKEN, createRemoteJWKSet(new URL(process.env.JWKS_URI)), {algorithms:['RS256']}); console.log('VALID'); console.log(JSON.stringify(payload,null,2)); } catch(e) { console.log('INVALID:',e.message); }"
如果未提供密钥,则仅执行结构和声明验证,并明确说明签名未验证。
输出格式
## JWT Validation Report
Structure: PASS
Claims: PASS — exp 2025-06-15T12:00:00Z (expires in 2h)
Signature: PASS — RS256, key kid "abc123"
Result: VALID
失败时:
## JWT Validation Report
Structure: PASS
Claims: FAIL — exp 2024-01-15T12:00:00Z (expired 6 months ago)
Signature: SKIPPED
Result: INVALID — token expired
安全规则
- 绝不信任令牌的
algHeader 来进行验证。 始终使用用户预期的算法,或与所提供密钥类型相匹配的算法。信任该 Header 会导致算法混淆攻击:攻击者将 RS256 切换为 HS256,并使用公钥作为 HMAC 密钥进行签名。 - 验证调用中始终将
algorithms指定为明确的允许列表。绝不传入algorithms: [decoded.header.alg]。 - 绝不将密钥或令牌作为命令行字面参数传递。 使用环境变量。参数会显示在 shell 历史记录和
ps输出中。 alg: none— 将其标记为严重安全问题。该令牌未签名,不能信任。- 如果未提供密钥,则仅验证结构和声明。明确说明:“签名未验证 — 令牌的真实性未知。”
评论
支持 Markdown