在谈及jwt原理前,我们其实对jwt并不陌生,对于有经验的码农,大都听过或者实践过,对于一些初学者,凡是谈及安全方面的问题,总是觉得很复杂,感觉不是自己能搞得懂得,但其实无非也是加密解密的过程,不要想的太复杂,我们先说一说JWT在生产上的应用
JWT在生产上的应用
-
传递用户身份信息: JWT 通常用于在前端和后端之间传递用户身份信息。前端登录成功后,服务端生成 JWT 令牌并返回给前端。前端随后将令牌包含在每个请求的头部,以便服务端验证用户身份。
-
无状态身份验证: JWT 的一大优势是它是无状态的,服务端不需要存储用户的登录状态。每个请求都包含了足够的信息,使得服务端能够验证用户身份而无需查询数据库。
-
单点登录(SSO): JWT 也被广泛用于实现单点登录。用户只需在一个认证中心登录一次,然后通过 JWT 令牌在多个服务之间共享身份信息,而无需重复登录。
-
过期处理: JWT 中通常包含一个过期时间(
exp
),服务端在验证令牌时会检查这个过期时间,确保令牌仍然有效。过期时间过后,令牌将不再被接受,这有助于提高安全性。
=========================================================================
前面我提到了,所谓生成令牌,验证解析,无非就是有一套自己的加密,解密,验证逻辑
生成JWT
在生成 JWT 令牌时,我们首先选择一个密钥(secretKey
),这个密钥只有服务端知道。然后,我们定义一个包含用户身份信息和其他声明的 payload
。最后,我们使用选定的签名算法(例如 HS256)对 payload
进行签名,生成最终的 JWT 令牌。
public class JwtGenerator {public static String generateToken() {// 设置密钥String secretKey = "your_secret_key";// 定义要包含在令牌中的声明String token = Jwts.builder().setSubject("john_doe").claim("user_id", 123).setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 令牌有效期为一天.signWith(SignatureAlgorithm.HS256, secretKey).compact();return token;}public static void main(String[] args) {String token = generateToken();System.out.println(token);}
}
原理
-
密钥选择: 选择一个安全的随机密钥,确保只有授权的服务端知道这个密钥。
-
Payload: Payload 是一个 JSON 对象,包含了我们想要传递的信息,例如用户身份信息、权限等。它是令牌的主体部分。
-
签名: 使用密钥对 Payload 进行签名,生成签名部分。签名的目的是确保令牌在传输过程中没有被篡改。
验证和解析 JWT 令牌
在接收到 JWT 令牌后,服务端需要验证令牌的有效性,并解析其中的信息。
public class JwtValidator {public static void validateToken(String token) {// 设置密钥String secretKey = "your_secret_key";try {// 验证令牌并解码 payloadClaims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();// 在此处可以检查令牌中的声明,例如过期时间// 如果过期时间在当前时间之前,则说明令牌已过期System.out.println("Token is valid. Claims: " + claims);} catch (SignatureException e) {System.out.println("Invalid token signature.");}}public static void main(String[] args) {String receivedToken = "your_received_token";validateToken(receivedToken);}
}
原理
-
解析器创建: 使用相同的密钥创建一个 JWT 解析器。这个解析器将用于验证和解析令牌。
-
验证签名: 解析器通过比对令牌中的签名和使用密钥重新计算的签名来验证令牌的完整性。如果签名不匹配,说明令牌可能被篡改。
-
解码 Payload: 如果签名验证通过,解析器会解码令牌中的 Payload 部分。这样,服务端就能获取令牌中包含的用户身份信息和其他声明。
在生产中的应用:
-
传递用户身份信息: JWT 通常用于在前端和后端之间传递用户身份信息。前端登录成功后,服务端生成 JWT 令牌并返回给前端。前端随后将令牌包含在每个请求的头部,以便服务端验证用户身份。
-
无状态身份验证: JWT 的一大优势是它是无状态的,服务端不需要存储用户的登录状态。每个请求都包含了足够的信息,使得服务端能够验证用户身份而无需查询数据库。
-
单点登录(SSO): JWT 也被广泛用于实现单点登录。用户只需在一个认证中心登录一次,然后通过 JWT 令牌在多个服务之间共享身份信息,而无需重复登录。
-
过期处理: JWT 中通常包含一个过期时间(
exp
),服务端在验证令牌时会检查这个过期时间,确保令牌仍然有效。过期时间过后,令牌将不再被接受,这有助于提高安全性。
注意事项
对于敏感操作,仍然需要考虑使用 HTTPS 来保护令牌在传输过程中的安全性。此外,令牌中不应包含敏感信息,因为它可以被前端解码。敏感信息应该仅存储在安全的后端。