文档

了解 JWT 以及如何在应用程序中使用它。

什么是 JWT?

JSON Web Token (JWT) 是一个开放标准 (RFC 7519),它定义了一种紧凑且自包含的方式,以 JSON 对象的形式在各方之间安全地传输信息。

JWT 结构

JWT 由三个部分组成,用点分隔:Header.Payload.Signature。每个部分都经过 Base64URL 编码。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

头部

包含关于令牌的元数据,通常是签名算法 (alg) 和类型 (typ)。

负载

包含声明 (claims)。声明是关于实体(通常是用户)和附加元数据的陈述。

签名

用于验证令牌未被篡改。通过对编码后的头部和负载使用密钥或私钥签名创建。

常见声明

iss (签发者): 标识谁签发了令牌

sub (主题): 标识令牌的主题

aud (受众): 标识令牌的目标接收者

exp (过期时间): 过期时间 (Unix 时间戳)

nbf (不早于): 在此时间之前不得接受令牌

iat (签发时间): 令牌的签发时间

支持的算法

JWT 支持多种签名算法以满足不同用例。

HS256 / HS384 / HS512

HMAC with SHA-2 — 对称签名(签名和验证使用相同的密钥)

RS256 / RS384 / RS512

RSA with SHA-2 — 非对称签名(私钥签名,公钥验证)

ES256 / ES384 / ES512

ECDSA with SHA-2 — 椭圆曲线非对称签名

EdDSA (Ed25519)

EdDSA — 使用 Ed25519 的现代椭圆曲线签名

代码示例

多种编程语言的 JWT 即用型代码片段。

JavaScript (Node.js)
const jwt = require('jsonwebtoken');

// Sign
const token = jwt.sign(
  { sub: '1234567890', name: 'John Doe' },
  'your-secret-key',
  { algorithm: 'HS256', expiresIn: '1h' }
);

// Verify
const decoded = jwt.verify(token, 'your-secret-key');
console.log(decoded);
TypeScript (jose)
import { SignJWT, jwtVerify } from 'jose';

// Sign
const secret = new TextEncoder().encode('your-secret-key');
const token = await new SignJWT({ sub: '1234567890', name: 'John Doe' })
  .setProtectedHeader({ alg: 'HS256' })
  .setExpirationTime('1h')
  .sign(secret);

// Verify
const { payload } = await jwtVerify(token, secret);
console.log(payload);
Python
import jwt

# Sign
token = jwt.encode(
    {"sub": "1234567890", "name": "John Doe"},
    "your-secret-key",
    algorithm="HS256"
)

# Verify
decoded = jwt.decode(token, "your-secret-key", algorithms=["HS256"])
print(decoded)
Java
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

// Sign
String token = Jwts.builder()
    .setSubject("1234567890")
    .claim("name", "John Doe")
    .signWith(SignatureAlgorithm.HS256, "your-secret-key")
    .compact();

// Verify
Claims claims = Jwts.parser()
    .setSigningKey("your-secret-key")
    .parseClaimsJws(token)
    .getBody();
Go
import (
    "github.com/golang-jwt/jwt/v5"
)

// Sign
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "sub":  "1234567890",
    "name": "John Doe",
})
tokenString, err := token.SignedString([]byte("your-secret-key"))

// Verify
parsed, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
    return []byte("your-secret-key"), nil
})
claims := parsed.Claims.(jwt.MapClaims)
Ruby
require 'jwt'

payload = { sub: '1234567890', name: 'John Doe' }

# Sign
token = JWT.encode(payload, 'your-secret-key', 'HS256')

# Verify
decoded = JWT.decode(token, 'your-secret-key', true, algorithm: 'HS256')
puts decoded[0]
PHP
use Firebase\JWT\JWT;

$payload = [
    'sub' => '1234567890',
    'name' => 'John Doe',
];

// Sign
$token = JWT::encode($payload, 'your-secret-key', 'HS256');

// Verify
$decoded = JWT::decode($token, new Key('your-secret-key', 'HS256'));
print_r($decoded);
Rust
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation, EncodingKey, DecodingKey};

// Sign
let token = encode(
    &Header::new(Algorithm::HS256),
    &serde_json::json!({"sub": "1234567890", "name": "John Doe"}),
    &EncodingKey::from_secret("your-secret-key".as_ref()),
)?;

// Verify
let token_data = decode::<serde_json::Value>(
    &token,
    &DecodingKey::from_secret("your-secret-key".as_ref()),
    &Validation::new(Algorithm::HS256),
)?;
C# (.NET)
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var securityKey = new SymmetricSecurityKey(
    Encoding.UTF8.GetBytes("your-secret-key"));

// Sign
var token = new JwtSecurityToken(
    claims: new[] { new Claim("sub", "1234567890"), new Claim("name", "John Doe") },
    signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(token);

// Verify
var principal = new JwtSecurityTokenHandler().ValidateToken(tokenString,
    new TokenValidationParameters { ValidateIssuerSigningKey = true,
        IssuerSigningKey = securityKey, ValidateIssuer = false, ValidateAudience = false },
    out _);
Swift
import JWT

// Sign
let payload = JWTPayload(sub: "1234567890", name: "John Doe")
let signer = JWTSigner.hs256(key: Data("your-secret-key".utf8))
let token = try signer.sign(payload)

// Verify
let verifier = JWTVerifier.hs256(key: Data("your-secret-key".utf8))
let verified = try verifier.verify(token)