jwt-validate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJWT Validate
JWT验证
Verify a JWT's signature and validate its claims. Confirms the token is authentic, unexpired, and structurally sound.
验证JWT的签名并校验其声明,确认令牌真实可信、未过期且结构合规。
Validation Order
校验顺序
Check in this order. Stop and report at the first failure.
按以下顺序校验,遇到第一个失败项就停止并返回结果。
1. Structure
1. 结构
- Exactly 3 dot-separated parts, each valid base64url
- Header and payload parse as valid JSON
- Header contains ;
algis notalg(unless explicitly expected)none
- 恰好包含3个点号分隔的部分,每个部分都是合法的base64url格式
- 头部和载荷可解析为合法JSON
- 头部包含字段;
alg值不为alg(除非明确预期允许该值)none
2. Claims
2. 声明
- must be in the future (report time until expiry or how long ago it expired)
exp - must be in the past or present
nbf - must be in the past; flag if > 30 days old
iat - ,
iss,aud— if user provides expected values, they must matchsub - Allow 60 seconds clock skew tolerance on all time checks
- 必须为未来时间(报告距离过期的剩余时间或已过期时长)
exp - 必须为过去或当前时间
nbf - 必须为过去时间;如果超过30天需要标记
iat - 、
iss、aud— 如果用户提供了预期值,必须完全匹配sub - 所有时间检查允许60秒的时钟偏移容差
3. Signature
3. 签名
Requires the user to provide a secret, PEM public key, or JWKS URI. Always pass secrets and tokens via inline env vars to avoid shell history exposure.
Node.js (preferred):
First, ensure is available — install it globally if missing:
josebash
node --input-type=module -e "await import('jose')" 2>/dev/null || npm install -g joseThen verify the token:
bash
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:
bash
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 verification (Node.js):
bash
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); }"If no secret/key is provided, perform structure + claims validation only, and clearly state the signature was NOT verified.
需要用户提供密钥、PEM公钥或JWKS URI。请始终通过内联环境变量传递密钥和令牌,避免泄露shell历史记录。
Node.js(首选):
首先,确保已安装,若缺失则全局安装:
josebash
node --input-type=module -e "await import('jose')" 2>/dev/null || npm install -g jose然后验证令牌:
bash
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:
bash
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):
bash
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); }"如果未提供密钥/公钥,仅执行结构+声明校验,并明确说明签名未被核验。
Output Format
输出格式
undefinedundefinedJWT Validation Report
JWT Validation Report
Structure: PASS
Claims: PASS — exp 2025-06-15T12:00:00Z (expires in 2h)
Signature: PASS — RS256, key kid "abc123"
Result: VALID
On failure:
Structure: PASS
Claims: PASS — exp 2025-06-15T12:00:00Z (expires in 2h)
Signature: PASS — RS256, key kid "abc123"
Result: VALID
校验失败时:
JWT Validation Report
JWT Validation Report
Structure: PASS
Claims: FAIL — exp 2024-01-15T12:00:00Z (expired 6 months ago)
Signature: SKIPPED
Result: INVALID — token expired
undefinedStructure: PASS
Claims: FAIL — exp 2024-01-15T12:00:00Z (expired 6 months ago)
Signature: SKIPPED
Result: INVALID — token expired
undefinedSecurity Rules
安全规则
- Never trust the token's header for verification. Always use the algorithm the user expects or that matches the provided key type. Trusting the header enables algorithm confusion attacks where an attacker switches RS256 to HS256 and signs with the public key as an HMAC secret.
alg - Always specify as an explicit allowlist in verification calls. Never pass
algorithms.algorithms: [decoded.header.alg] - Never pass secrets/tokens as literal command-line arguments. Use environment variables. Args are visible in shell history and output.
ps - — Flag as a critical security issue. The token is unsigned and cannot be trusted.
alg: none - If no key is provided, validate structure and claims only. Clearly state: "Signature was NOT verified — token authenticity is unknown."
- 绝对不要信任令牌的头来做校验。 始终使用用户预期的算法,或与提供的密钥类型匹配的算法。信任该头部会导致算法混淆攻击,攻击者可将RS256切换为HS256,并用公钥作为HMAC密钥签名。
alg - 始终在校验调用中将指定为明确的允许列表,绝对不要传入
algorithms。algorithms: [decoded.header.alg] - 绝对不要将密钥/令牌作为字面量命令行参数传递。 请使用环境变量。参数会在shell历史和输出中可见。
ps - — 标记为严重安全问题。该令牌未签名,不可信任。
alg: none - 如果未提供密钥,仅校验结构和声明。明确说明: "Signature was NOT verified — token authenticity is unknown."