文章摘要
LIK.CC-GPT
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。它通过紧凑且自包含的方式(通常以JSON对象形式)传递声明(Claims),适用于身份验证、授权和信息交换等场景。 核心结构 JWT由三部分组成,用点(.)分隔: Header(头部) 包含令牌类型
JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在各方之间安全传输信息。它通过紧凑且自包含的方式(通常以JSON对象形式)传递声明(Claims),适用于身份验证、授权和信息交换等场景。
核心结构
JWT由三部分组成,用点(.
)分隔:
-
Header(头部)
- 包含令牌类型(
typ: "JWT"
)和签名算法(如alg: HS256
或RS256
)。 - 示例:
{"alg": "HS256", "typ": "JWT"}
- 使用Base64Url编码。
- 包含令牌类型(
-
Payload(载荷)
- 存放实际数据(声明),分为三类:
- Registered Claims(预定义声明):如
iss
(签发者)、exp
(过期时间)、sub
(主题)等。 - Public Claims(公开声明):自定义但需避免冲突的声明。
- Private Claims(私有声明):应用自定义的数据,如用户ID。
- Registered Claims(预定义声明):如
- 示例:
{"sub": "user123", "exp": 1620000000}
- 使用Base64Url编码。
- 存放实际数据(声明),分为三类:
-
Signature(签名)
- 将编码后的Header和Payload与密钥(Secret)通过指定算法(如HMAC SHA256)签名,确保数据完整性和真实性。
- 公式:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
完整JWT示例:
Header.Payload.Signature
→ xxxxx.yyyyy.zzzzz
工作流程
- 用户登录:客户端发送凭证(如用户名密码)到服务器。
- 生成JWT:服务器验证凭证,生成JWT并返回。
- 客户端存储:客户端将JWT保存(如LocalStorage或Cookie)。
- 携带Token请求:后续请求在
Authorization
头中携带JWT(如Bearer <token>
)。 - 服务器验证:服务器验证签名和声明(如是否过期)后处理请求。
优点
- 无状态:服务端无需存储会话信息,适合分布式系统。
- 跨域支持:适用于前后端分离、跨域API调用。
- 自包含性:Payload可直接包含用户信息,减少数据库查询。
- 灵活性:支持多种签名算法(对称HMAC或非对称RSA/ECDSA)。
缺点
- 无法撤销:签发后需等待过期,需结合黑名单或短期Token解决。
- 存储风险:客户端存储不当可能导致XSS攻击窃取Token。
- 数据暴露:Payload仅Base64编码(非加密),敏感信息需加密处理。
- 体积较大:相比Session ID,JWT可能增加请求头大小。
安全实践
- 使用HTTPS:防止Token在传输中被截获。
- 设置合理过期时间:缩短有效期,结合Refresh Token续签。
- 避免敏感数据:Payload中不存密码等机密信息。
- 签名算法选择:优先使用非对称算法(如RS256)增强安全性。
- 防范XSS:避免LocalStorage存储,使用HttpOnly Cookie。
应用场景
- 身份验证:用户登录后获取JWT,后续请求验证。
- 单点登录(SSO):一次登录多系统共享Token。
- API认证:微服务间通过JWT传递用户身份。
- 移动端认证:减少对Cookie的依赖。
示例代码(Python)
使用 PyJWT
库实现 JWT 的生成与验证:
1. 安装依赖
pip install pyjwt
2. 生成和验证 Token
import jwt
import datetime
# 生成 Token
def generate_jwt():
payload = {
"user_id": 123,
"role": "admin",
# 设置过期时间(1小时后)
"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}
secret = "your-secret-key"
token = jwt.encode(payload, secret, algorithm="HS256")
return token
# 验证 Token
def verify_jwt(token):
secret = "your-secret-key"
try:
decoded = jwt.decode(token, secret, algorithms=["HS256"])
return decoded
except jwt.ExpiredSignatureError:
print("Token 已过期")
except jwt.InvalidTokenError:
print("无效 Token")
# 测试
if __name__ == "__main__":
token = generate_jwt()
print("生成的 Token:", token)
decoded_data = verify_jwt(token)
if decoded_data:
print("解码后的数据:", decoded_data)
总结
JWT适用于需要无状态、跨域或分布式的场景,但需注意安全性和存储方式。在设计时需权衡便利性与风险,结合业务需求选择合适的验证机制。