1. 什么是 JWT?它由哪几部分组成?
JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在网络应用间安全传递声明。它由三部分组成,用 .
分隔:
Header(头部):通常包含令牌类型(如
JWT
)和签名算法(如HS256
)。Payload(负载):包含声明(Claims),如用户身份、权限、过期时间等。
Signature(签名):使用 Header 中指定的算法,对 Header 和 Payload 签名,确保数据未被篡改。
结构示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. // Header
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. // Payload
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c // Signature
2. JWT 的三部分分别存储哪些信息?
Header:
{ "alg": "HS256", // 签名算法 "typ": "JWT" // 令牌类型 }
Payload:
{ "sub": "1234567890", // 主题(通常是用户 ID) "name": "John Doe", // 自定义声明 "iat": 1516239022, // 签发时间(Issued At) "exp": 1516325422 // 过期时间(Expiration Time) }
Signature:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), your-256-bit-secret )
3. JWT 的工作原理是什么?
用户登录:输入凭证发送到服务器
生成 JWT:服务器验证通过后生成包含用户信息的 JWT
发送 JWT:将 JWT 返回给客户端
存储 JWT:客户端本地存储(如 localStorage、cookie)
发送请求:每次请求携带 JWT(通常在 Authorization 头部)
验证 JWT:服务器提取并验证 JWT 的有效性
处理请求:根据 JWT 信息进行身份验证和授权
6. JWT 的优点是什么?
无状态:无需服务器存储 Session,适合微服务和分布式系统。
跨域支持:可通过
localStorage
存储,支持跨域请求。扩展性:Payload 可自定义声明,灵活携带用户信息。
安全性:签名机制确保数据完整性,支持多种加密算法。
移动端友好:易于在移动应用中实现。
7. JWT 的常见算法有哪些?
对称加密:
HS256
(HMAC-SHA256):使用相同密钥签名和验证。HS384
(HMAC-SHA384)、HS512
(HMAC-SHA512)。
非对称加密:
RS256
(RSA-SHA256):使用私钥签名,公钥验证。ES256
(ECDSA-SHA256):椭圆曲线加密,性能更高。
8. JWT 中重要的注册声明(Claims)有哪些?
标准声明(非强制):
iss
(Issuer):签发者。sub
(Subject):主题(通常是用户 ID)。aud
(Audience):受众。exp
(Expiration Time):过期时间(Unix 时间戳)。nbf
(Not Before):生效时间(在此之前令牌无效)。iat
(Issued At):签发时间。jti
(JWT ID):唯一标识符(用于防重放攻击)。
9. JWT 与 Session 的区别是什么?
特性 | JWT | Session |
---|---|---|
存储位置 | 客户端(如 localStorage ) | 服务器(如 Redis、内存) |
状态性 | 无状态 | 有状态 |
跨域支持 | 支持(需注意 CSRF) | 不支持(依赖 Cookie) |
扩展性 | 高(Payload 可自定义) | 低(需查询服务器) |
安全性 | 依赖签名和 HTTPS | 依赖 Cookie 安全(如 HttpOnly ) |
性能 | 无需数据库查询 | 需查询数据库或缓存 |
10. 什么是密钥混淆攻击?如何防止?
攻击原理: 攻击者通过猜测或泄露的密钥,伪造合法 JWT 签名。例如:
使用公共密钥(如
RS256
的公钥)尝试签名。利用弱密钥(如短字符串、默认值)进行暴力破解。
防范措施:
使用足够复杂的密钥(如 256 位随机字符串)。
定期轮换密钥。
避免在客户端或公开代码中暴露密钥。
优先使用非对称加密(如
RS256
),私钥仅保存在服务器。
11. JWT 的安全风险有哪些?如何降低?
1. 签名未校验攻击
漏洞原理:开发人员混淆 verify () 和 decode () 方法,仅解码而不验证签名
攻击步骤
登录获取 JWT
修改 Payload 中的用户身份(如 sub 改为 administrator)
重新生成 JWT 并发送请求
绕过验证访问管理员功能
2. 签名用 None 攻击
漏洞原理:JWT Header 中 alg 设为 “none” 表示不签名,任何 token 都有效
攻击步骤
登录获取 JWT
修改 Header 的 alg 为 “none”
修改 Payload 中的用户身份
移除 Signature 部分(保留点分隔符)
发送请求冒充管理员
3. JWT 字典爆破攻击
漏洞原理:使用默认或弱密钥签名 JWT
攻击步骤
获取有效的 JWT
使用 hashcat 等工具结合字典暴力破解密钥
命令示例:
hashcat -a 0 -m 16500 <jwt> <wordlist>
使用破解的密钥生成管理员 JWT
4. JWK Header 注入攻击
漏洞原理:服务器错误使用 jwk 参数中嵌入的密钥
攻击步骤
生成新的 RSA 密钥对
修改 JWT 的 Payload 为管理员身份
在 Header 中注入 JWK 参数(包含生成的公钥)
使用私钥签名 JWT
发送请求绕过验证
5. 敏感信息泄露攻击
漏洞原理:JWT 中包含敏感信息且未加密
攻击步骤
获取 JWT 令牌
解码 Payload 获取敏感信息(如密码、用户身份)
使用获取的信息进行登录或进一步攻击
11. JWT 如何实现刷新机制?
双令牌方案:
访问令牌(Access Token):短期有效(如 15 分钟),用于 API 请求。
刷新令牌(Refresh Token):长期有效(如 7 天),存储在安全位置(如
HttpOnly
Cookie)。
流程:
访问令牌过期时,客户端使用刷新令牌向
/refresh
端点请求新的访问令牌。服务器验证刷新令牌,生成新的访问令牌并返回。
安全措施:
刷新令牌仅能使用一次,使用后立即失效。
存储刷新令牌时使用
Secure
和HttpOnly
属性。记录令牌使用日志,检测异常行为。
12. JWT 是如何实现签名和验证的?加密和签名的区别是什么?
签名流程:
服务器使用 Header 中指定的算法(如
HS256
),对 Header 和 Payload 进行哈希。使用密钥对哈希值签名,生成 Signature。
验证流程:
客户端接收到 JWT,分离三部分。
重新计算 Header 和 Payload 的签名(使用相同算法和密钥)。
比较计算结果与接收到的 Signature 是否一致。
加密 vs 签名:
加密:将数据转换为密文,防止未授权读取(如 AES 加密)。
签名:验证数据来源和完整性,不加密数据(如 HMAC)。
13. 对比 Cookie、Session 和 Token 的区别,并说明 JWT 的应用场景。
维度 | Cookie | Session | Token |
---|---|---|---|
存储位置 | 客户端(浏览器) | 服务器端(如内存、数据库) | 客户端(如 Cookie、localStorage) |
状态性 | 客户端存储,服务器无状态(仅读) | 服务器需维护会话状态 | 服务器无状态(无需存储,通过验证令牌即可) |
传输方式 | 随 HTTP 请求自动携带(Cookie 头) | 依赖 Cookie 传递 Session ID | 需手动嵌入请求(如 Header、表单) |
安全性 | 易被 XSS 窃取(无 HttpOnly 时) | 相对安全(Session ID 仅在客户端) | 依赖签名验证,安全性可控 |
扩展性 | 受浏览器存储大小限制(约 4KB) | 服务器存储压力大(分布式系统需共享会话) | 无服务器存储压力,适合分布式系统 |
JWT 的应用场景
分布式系统认证:跨服务、跨域名的统一身份验证(如微服务架构中,无需共享 Session)。
API 接口授权:第三方应用调用 API 时,通过 JWT 传递用户权限,避免频繁登录。
单点登录(SSO):用户一次登录后,通过 JWT 在多个关联系统中实现免密访问。
短期授权