JWT的介绍和使用
1. 什么是JWT?
JWT(JSON Web Tokens)是一种广泛应用于Java平台上的轻量级安全规范,用于在各方之间安全地传输信息。JWT作为一个开放标准(RFC 7519),其核心目标是在Web环境中提供一种紧凑且安全的方式来传递JSON对象,这些对象被称为“声明”(claims)。JWT特别适合于需要验证用户身份和授权的场景,如单点登录(SSO)、API认证等。
2. 官方地址
首页地址:https://jwt.io/
文档地址:https://jwt.io/introduction
3. JWT的基本结构
WT由三部分组成,各部分通过.
分隔:
- Header(头部):描述了JWT的元数据,比如其签名算法(如HMAC SHA256或RSA)。此部分通常会被Base64Url编码形成JWT的第一部分。
- Payload(载荷):包含了声明,即传输的数据。这可以是用户ID、角色、过期时间等任何需要传递的信息。同样,这部分也会被Base64Url编码形成JWT的第二部分。声明可以是公开的,也可以是私有的,具体取决于应用场景。
- Signature(签名):通过对前两部分进行指定算法的签名来确保JWT的完整性和来源的真实性。签名过程会使用一个秘钥(secret)或公钥/私钥对,具体取决于选择的算法。签名使得接收方能够验证JWT是否被篡改。
4. 支持的算法
JWT支持多种签名和加密算法,这些算法主要用于确保JWT的安全性和完整性。以下是JWT中可以使用的几种典型算法:
- HMAC (Hash-based Message Authentication Code):
- HS256 (HMAC using SHA-256): 这是最常用的对称加密算法,使用一个共享密钥对JWT的头部和载荷进行签名。
- HS384 (HMAC using SHA-384): 类似HS256,但使用SHA-384哈希算法,提供更强的安全性。
- HS512 (HMAC using SHA-512): 同样是对称加密,使用SHA-512哈希算法,安全性更高。
- RSA (Rivest–Shamir–Adleman):
- RS256 (RSA Signature with SHA-256): 非对称加密算法,使用RSA私钥对JWT进行签名,公钥用于验证签名。适合于需要验证JWT来源的场景。
- RS384 (RSA Signature with SHA-384): 使用SHA-384作为哈希函数的RSA签名。
- RS512 (RSA Signature with SHA-512): 使用SHA-512作为哈希函数的RSA签名,提供最高级别的安全性。
- ECDSA (Elliptic Curve Digital Signature Algorithm):
- ES256 (ECDSA using P-256 and SHA-256): 基于椭圆曲线密码学的签名算法,使用P-256曲线和SHA-256哈希函数。
- ES384 (ECDSA using P-384 and SHA-384): 类似于ES256,但使用P-384曲线和SHA-384哈希。
- ES512 (ECDSA using P-521 and SHA-512): 使用P-521曲线和SHA-512哈希函数。
- None:
- None: 表示没有签名算法。虽然JWT规范中提到了这个选项,但实际上在没有签名的情况下JWT是不安全的,因为任何人都可以修改其内容,因此在实际应用中应避免使用。
选择哪种算法通常取决于安全性需求、性能考量以及是否需要非对称加密提供的额外特性。在大多数情况下,HS256因其简单和性能较好而被广泛使用,而对于需要更高安全级别或者需要验证JWT来源的场景,则可能会选择RS256或ES256等非对称算法。
另外如果从源码中也能够看到支持的算法都有哪些:
5. 相关异常
解析JWT时可能会遇到多种异常情况,这些异常主要反映了JWT的不同问题。以下是一些常见的JWT解析异常及其含义:
- MalformedJwtException(格式异常): 当JWT的格式不符合规范时抛出,比如缺少
.
分隔符,或者Base64Url编码不正确。 - SignatureException(签名异常): 如果JWT的签名验证失败,即计算出的签名与JWT中携带的签名不匹配,将抛出此异常。
- ExpiredJwtException(过期异常): 当JWT的过期时间(Expiration Claim,exp)已经过去,尝试解析时会抛出此异常。
- UnsupportedJwtException(不支持的JWT异常): 当JWT的格式或类型不被解析库支持时,例如,如果JWT是一个Signed JWT但库只支持Plain JWT,将抛出此异常。
- IllegalArgumentException(非法参数异常): 当传给JWT解析方法的参数不合法时,比如秘钥为空,可能会抛出此异常。
- PrematureJwtException(过早异常): 尽管不常见,但如果JWT含有“nbf”(Not Before)声明,并且当前时间在该声明指定的时间之前,解析时会抛出此异常。
- InvalidClaimException(无效声明异常): 如果JWT中的某个声明值不符合预期,例如,一个要求必须存在的声明缺失,或者声明的值不符合校验规则,可能会抛出此类异常。
- io.jsonwebtoken.security.SignatureException: 特定于某些JWT库(如jjwt),当签名验证逻辑出现问题时抛出。
这些异常通常需要在代码中被捕获并适当处理,例如,过期异常可能需要提示用户重新登录,而格式异常则可能意味着传入的JWT字符串有问题,需要检查其生成或传输过程。由于JWT解析通常在过滤器等早期处理环节完成,这些异常的处理方式需考虑不影响正常的错误处理流程,可能需要自定义异常处理机制而非依赖于全局异常处理器。