艾林博客 - 技术交流与经验分享的个人博客

深入理解JWT:原理、优缺点及使用场景

Liner51

Liner51

1个月前更新

在现代Web开发中,用户身份认证是一个极为重要的环节。随着应用架构逐渐趋向分布式,传统的会话认证逐渐暴露出种种不足,而**JWT(JSON Web Token)**作为一种基于Token的认证机制,凭借其轻量化、跨语言等特点,迅速成为开发者的首选。

本文将深入解析JWT的工作原理、结构组成、优缺点及其常见的使用场景,帮助您全面了解JWT并在实际项目中正确地使用它。


一、什么是JWT?

JWT(JSON Web Token)是一种基于JSON格式的令牌(Token),它是一种开放标准(RFC 7519),用于在各方之间安全地传递信息。JWT通常用于认证和授权场景中。

JWT的核心思想是:将用户身份信息通过数字签名加密后生成一个令牌,客户端携带该令牌与服务器交互,完成认证和授权操作。


二、JWT的结构

JWT由三部分组成,每部分之间用.分隔,完整的JWT格式如下:

Header.Payload.Signature

1. Header(头部)

Header 包含两部分信息:

  • 类型(typ):固定为 "JWT"。
  • 算法(alg):声明使用的签名算法,如 HMAC SHA256 或 RSA。

示例:

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

Header 使用 Base64 编码后可能长成这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

2. Payload(载荷)

Payload 是JWT的主体部分,包含需要传递的用户信息(Claims),它通常分为以下三类:

  • Registered Claims(标准声明):如 iss(签发者)、exp(过期时间)、sub(主题)、aud(受众)。
  • Public Claims(公共声明):自定义的公共信息,需避免冲突。
  • Private Claims(私有声明):双方约定的信息。

示例 Payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "exp": 1516242622
}

Payload 使用 Base64 编码后可能长成这样:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjM5MzIyfQ

3. Signature(签名)

签名用于验证JWT的完整性,确保Token未被篡改。签名的生成公式如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

生成的签名示例:

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

最终得到的JWT完整格式如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjM5MzIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

三、JWT的工作流程

  1. 用户登录:用户通过用户名和密码向服务器发起登录请求。
  2. 服务器生成JWT
    • 验证用户身份后,服务器使用预定义的密钥(Secret)创建JWT。
    • JWT中包含用户数据及过期时间。
  3. 客户端存储JWT
    • 客户端(例如浏览器或移动端)将JWT存储在LocalStorageHTTP Only Cookie中。
  4. 客户端携带JWT访问资源
    • 客户端每次向服务器发送请求时,在请求头的 Authorization 字段中携带JWT:
      Authorization: Bearer <JWT>
      
  5. 服务器验证JWT
    • 服务器使用密钥验证JWT的合法性。
    • 验证通过则返回资源,验证失败则返回 401 Unauthorized

四、JWT的优缺点

优点

  1. 无状态认证
    • JWT是无状态的,服务器无需存储会话信息,降低了服务器压力,更适合分布式系统。
  2. 跨语言支持
    • JWT是基于JSON的,能够在不同语言和平台之间无缝传递。
  3. 高效
    • JWT一次生成后,后续请求只需携带JWT即可,无需多次查询数据库。
  4. 可扩展性
    • Payload可携带自定义信息,满足不同业务需求。

缺点

  1. 存在安全隐患
    • JWT一旦被窃取,除非过期,否则攻击者可以使用它进行伪装。
  2. Token不可撤销
    • JWT是无状态的,无法轻易地使某个已签发的Token失效(除非引入额外的黑名单机制)。
  3. Payload可以被解码
    • 虽然JWT经过签名,但Payload部分是可解码的,敏感数据必须加密或避免直接暴露在Payload中。

五、JWT的常见使用场景

1. 用户认证

JWT最常见的用途是用户认证,通过生成的Token验证用户身份。多用于:

  • Web应用登录认证
  • 移动端用户认证
  • 第三方应用OAuth认证

2. 单点登录(SSO)

在分布式系统或微服务架构中,SSO是一个重要的需求。JWT可以跨服务传递用户身份信息,实现无缝登录。


3. API认证

在RESTful API中,JWT常用于保护接口,避免未授权的访问。


4. 临时权限控制

通过设置短时效的JWT(如15分钟有效),可以满足一些临时的权限需求,例如一次性访问链接、验证码等。


六、如何安全地使用JWT?

  1. 使用HTTPS
    • 确保通信加密,防止Token被中间人窃取。
  2. 设置合理的过期时间
    • 为JWT设置较短的过期时间,减少Token被滥用的风险。
  3. 使用HTTP Only Cookie存储Token
    • 避免Token被JavaScript脚本获取,防止XSS攻击。
  4. 避免在Payload中存储敏感信息
    • Payload是可解码的,敏感数据应加密或不存储在Token中。
  5. 引入黑名单机制
    • 在某些场景下,创建Token黑名单机制以支持Token撤销。
  6. 定期更换密钥
    • 定期更新JWT签名密钥,提升安全性。

七、JWT常见问题解答

1. 为什么Payload可以被解码?

JWT的Payload是Base64编码的,主要目的是便于传输,而不是加密。敏感信息不要直接存储在Payload中。

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

  • Session:服务器存储会话信息,适合小规模应用。
  • JWT:无状态,客户端存储Token,适用于分布式系统。

3. 如何使JWT失效?

  • 等待JWT过期。
  • 使用黑名单机制。
  • 修改签名密钥,使先前的JWT失效。

八、总结

JWT是一种高效、跨平台的认证机制,在现代Web开发中得到了广泛应用。然而,在使用JWT时,必须注意其安全性限制,并结合具体业务场景合理设计。例如,可以利用短时效Token避免滥用,或者配合黑名单机制解决不可撤销的问题。

通过正确地理解和使用JWT,您将能够构建更加高效、可靠的身份认证系统。

The End
案例分析

喜欢就支持一下把!

(0)
我们的事业是正义的,我们的团结是坚强的。

约·迪金森

为您推荐