侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 192 篇文章
  • 累计创建 18 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JWT:常用的面试题和答案

拾荒的小海螺
2024-12-18 / 0 评论 / 0 点赞 / 11 阅读 / 9008 字

1. 什么是 JWT,它的结构是怎样的?

答:JWT 是 JSON Web Token 的简称,是一种开放标准(RFC 7519),用于在各方之间以 JSON 对象安全地传输信息。JWT 的设计目的是为了确保数据的完整性和来源可靠性。

JWT 的结构由三个部分组成:

  • Header(头部):描述 JWT 的元信息,包括类型(通常为 JWT)和签名算法(如 HS256、RS256)。
  • Payload(负载):存储具体的信息或声明(claims),比如用户 ID、过期时间等。
  • Signature(签名):通过 Header 和 Payload 使用指定的算法生成,用于验证 JWT 的完整性。

JWT Token 实例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

1734507736649.jpg


2. JWT 如何保证数据的完整性?

答:JWT 使用签名(Signature)来保证数据的完整性。签名的生成方式是:

  • 将 Header 和 Payload 分别进行 Base64Url 编码。
  • 使用指定的签名算法(如 HMAC-SHA256 或 RSA)对编码后的字符串进行签名。
  • 签名结果会附加到 JWT 的尾部,形成完整的 Token。

在验证过程中,服务器会重新计算签名并与收到的 JWT 签名进行对比。如果签名一致,则表明数据未被篡改。

注意:签名只能保证数据未被修改,但不能保护数据的机密性,Header 和 Payload 依然是可解码的。


3. JWT 的优缺点是什么?

优点:

  • 无状态:JWT 不需要在服务器端保存用户会话数据,所有信息都存储在 Token 内,适合分布式系统。
  • 易扩展:负载部分可以存储任意 JSON 格式的数据。
  • 签名验证:通过签名可以验证数据的完整性和来源。
  • 跨语言支持:JWT 标准被广泛支持,几乎所有语言都能使用。

缺点:

  • 明文传输:JWT 的 Header 和 Payload 是 Base64Url 编码的,敏感信息容易暴露(除非使用加密)。
  • Token 长度较长:与普通 Session ID 相比,JWT 的长度会占用更多带宽。
  • 无法撤销:JWT 是无状态的,一旦签发,无法强制使其失效(除非使用黑名单等机制)。

4. JWT 是明文传输吗?如何保护数据的机密性?

答:是的,JWT 的 Header 和 Payload 是 Base64Url 编码的,这种编码方式是可解码的,因此它是明文的。如果 JWT 包含敏感信息(如用户密码等),需要额外加密。

保护数据机密性的方法:

  • 使用 HTTPS:通过 HTTPS 协议传输 JWT,防止被窃听。
  • 加密敏感数据:在存储到 Payload 中之前,对敏感数据进行加密。
  • 使用 JWE:JWE(JSON Web Encryption)是 JWT 的扩展,它可以加密整个 Payload。

5. 如何验证 JWT 的合法性?

答:验证 JWT 的合法性包括以下步骤:

  • 解码 JWT,获取 Header 和 Payload。
  • 使用同样的算法(如 HS256)和密钥重新计算签名。
  • 比较计算出的签名和 JWT 的签名部分,如果一致,则合法。
  • 检查 Payload 中的声明(如 exp、iat)是否符合业务需求。

6. JWT 的有效期如何设置?

答:JWT 的有效期通过 Payload 中的声明字段设置:

  • iat(Issued At):JWT 签发的时间。
  • exp(Expiration Time):JWT 的过期时间,通常是一个时间戳。
  • nbf(Not Before):JWT 开始生效的时间。
{
  "iat": 1696563456,
  "exp": 1696567056,
  "nbf": 1696563456
}

当接收到 JWT 时,服务器会检查 exp 是否已过期,如果过期则拒绝请求。


7. JWT 的签名算法有哪些?

答:JWT 支持以下几种常用的签名算法:

  • HMAC-SHA(对称算法):如 HS256、HS384、HS512。
    使用单一密钥进行签名和验证,简单易用,但密钥需要妥善保管。
  • RSA/ECDSA(非对称算法):如 RS256、ES256。
    使用公钥和私钥,私钥签名,公钥验证,更加安全,适合分布式系统。

示例 Header:

{
  "alg": "HS256",
  "typ": "JWT"
}

8. 如何使 JWT 失效?

答:JWT 是无状态的,一旦签发就无法直接撤销。但可以通过以下方法实现失效:

  • 设置短有效期:通过 exp 设置较短的过期时间,减少长时间有效的风险。
  • 黑名单机制:将失效的 JWT 的 ID 或签发信息存储在服务器的黑名单中,每次验证时检查黑名单。
  • 更新密钥:更换签名密钥,所有旧的 JWT 都会失效。

9. JWT 如何防止重放攻击?

答:防止重放攻击的措施:

  • 使用 jti(JWT ID)字段:在每个 JWT 中添加唯一标识符,并在服务器端存储,防止重复使用。
  • 设置短有效期:通过 exp 限制 Token 的生命周期。
  • 结合 HTTPS:通过加密传输防止 Token 被窃取。

10. JWT 和 Session 的区别是什么?

对比点 JWT Session
存储位置 客户端(Token 存储在前端) 服务器(会话信息存储在服务端)
状态 无状态 有状态
扩展性 更适合分布式系统,易扩展 单点系统较方便,多节点需要共享会话
安全性 签名保证数据完整性,但内容是明文 数据保存在服务器,默认更安全
失效机制 需要通过黑名单或更新密钥实现 服务端直接销毁会话

11. JWT 是否适合大规模分布式系统?为什么?

答:JWT 非常适合大规模分布式系统,原因如下:

  • 无状态性:JWT 不依赖服务端存储会话信息,完全由客户端携带,适合多节点系统,不需要共享会话。
  • 跨语言支持:JWT 是标准协议,不依赖特定语言或框架,便于在多语言、多服务间通信。
  • 灵活性:JWT 的 Payload 可以携带多种信息(如权限、角色等),方便系统扩展。

注意:在大规模系统中,需要使用以下策略避免 JWT 带来的问题:

  • Token 短生命周期:减少长期有效的 Token 风险。
  • 刷新机制:提供 Refresh Token 来重新生成短期有效的 Access Token。
  • 签名密钥管理:使用非对称加密算法(如 RSA),在多个服务之间共享公钥。

12. 如何实现 JWT 的 Token 刷新机制?

答:实现 Token 刷新通常需要引入两种 Token:

  • Access Token:短生命周期(如 15 分钟),用于访问受保护的资源。
  • Refresh Token:生命周期较长(如 7 天),用于生成新的 Access Token。

实现流程:

  • 客户端请求资源时携带 Access Token。
  • 如果 Access Token 过期,使用 Refresh Token 请求服务器,服务器验证后生成新的 Access Token。
  • 如果 Refresh Token 也过期,用户需要重新登录。

注意:Refresh Token 需要在服务端存储(如数据库、Redis)或使用更加安全的签名算法保护。


13. 如何设计安全的 JWT 签发和验证流程?

答:设计安全的 JWT 签发和验证流程需要遵循以下原则:

  • 使用 HTTPS:确保传输过程的安全性,防止中间人攻击。
  • 选择合适的签名算法:
    如果是单机服务:可以使用对称算法(如 HS256)。
    如果是分布式服务:推荐使用非对称算法(如 RS256),签发时使用私钥,验证时使用公钥。
  • 设置短生命周期:exp 字段设置较短的有效期。
  • 不在 JWT 中存储敏感信息:如密码、银行卡号等。
  • 验证关键字段:如 iss(签发者)、aud(接收方)和 iat(签发时间)。
  • 引入黑名单机制:用于处理需要立即失效的 Token。

14. JWT 是否可以用于授权?如何实现?

答:是的,JWT 不仅可以用于认证,还可以用于授权。

  • 在 Payload 中添加用户权限相关字段,例如:
{
  "sub": "1234567890",
  "role": "admin",
  "permissions": ["read", "write", "delete"]
}
  • 服务端在验证 JWT 后,根据 role 或 permissions 字段决定用户是否有权限执行某些操作。
  • 客户端可以根据 Payload 内容调整 UI 显示,比如隐藏没有权限的按钮。

15. JWT 和 OAuth 的关系是什么?

答:JWT 和 OAuth 是两种不同的技术,但可以结合使用:

  • OAuth 是一个授权框架,用于授权第三方应用访问资源。
  • JWT 是一种令牌格式,常用于 OAuth 的 Access Token。

结合点:

  • 在 OAuth 2.0 中,JWT 常被用作 Access Token 的格式。
  • OAuth 负责授权逻辑,JWT 负责在授权完成后传递认证和授权信息。

用户登录成功后,OAuth 授权服务器生成一个 JWT,客户端使用此 JWT 访问资源服务器。


16. 如何防止 JWT 被盗用?

答:防止 JWT 被盗用需要多种安全策略:

  • 使用 HTTPS:加密传输,防止网络窃听。
  • Token 短生命周期:即使 Token 被盗,生命周期结束后也会失效。
  • 绑定 IP 或设备信息:在 Payload 中存储 IP 地址或设备信息,验证时确保与当前请求一致。
  • 双 Token 机制:使用短期 Access Token 和长期 Refresh Token,Access Token 被盗后风险可控。
  • 签名密钥保护:密钥泄露会导致伪造 Token,需要使用安全的密钥管理工具(如 AWS KMS)。

17. 为什么 JWT 不适合存储大量数据?

答:JWT 的主要设计目标是传递少量的认证或授权信息,而不是用来存储大量数据。

原因:

  • 带宽浪费:JWT 每次请求都需要携带完整的 Token,数据量过大会浪费带宽。
  • 性能问题:解码和验证较大的 Token 会增加服务器负担。
  • 安全性问题:存储大量数据可能增加敏感信息泄露的风险。

建议:

  • 在 JWT 中只存储必要的声明(如用户 ID 和权限)。
  • 使用后端数据库或缓存(如 Redis)存储额外的用户数据。

18. JWT 如何处理多用户多设备登录场景?

答:在多用户、多设备场景中,需要处理以下问题:

  • 区分设备:在 JWT 的 Payload 中添加设备标识(如设备 ID 或 User-Agent)。
{
  "sub": "1234567890",
  "device": "device123"
}
  • 多设备同时登录:
    服务端允许同一用户在多个设备上生成独立的 JWT。
    在数据库中为每个设备维护独立的 Token 信息,便于管理。
  • 单设备登录:
    新设备登录时,注销其他设备的 Token。
    通过维护 Token 的状态表(如 Redis),使之前的 Token 无效。

19. JWT 的 Payload 是否可以被篡改?

答:JWT 的 Payload 是可以被修改的,但篡改后的 Token 无法通过签名验证。

  • JWT 的签名(Signature)是根据 Header 和 Payload 生成的,任何篡改都会导致签名验证失败。
  • 服务器在验证时会重新生成签名,与 JWT 的签名部分对比,发现不一致就拒绝请求。

20. 如何使用 JWT 实现用户注销功能?

答:由于 JWT 是无状态的,无法直接从服务器“注销”用户,但可以通过以下方法实现:

  • 短生命周期:
    将 JWT 的有效期设置很短,用户下次请求需要重新获取 Token。
  • 黑名单机制:
    在服务端维护一个黑名单,将需要注销的 JWT 的 jti 存入黑名单。
    每次验证 Token 时,检查黑名单,如果存在则拒绝请求。
  • Token 刷新策略:
    当用户选择注销时,将当前 Refresh Token 标记为失效,无法再生成新的 Access Token。
0

评论区