TipsTipsJWT令牌
CAMELLIAJWT令牌
1. 什么是JWT令牌
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息作为 JSON 对象。它主要由三部分组成,通过点号(.)分隔:
- Header(头部):包含令牌的类型(即JWT)和使用的签名算法(例如HMAC SHA256或RSA)。
- Payload(载荷):包含令牌的声明(claim),即实际传输的信息,例如用户ID、角色、权限等。
- Signature(签名):用于验证发送方是否有权创建令牌,确保信息未被篡改。
JWT的工作流程通常如下:
- 生成令牌:在用户身份验证成功后,服务器根据用户信息和配置生成一个JWT,并将其发送给客户端。
- 验证令牌:客户端收到JWT后,可以存储在本地并在未来的API请求中发送该令牌。
- 使用令牌:服务端收到JWT后,会验证签名,解析载荷中的信息,并根据需要做出响应。
JWT的优点包括:
- 无状态:服务器不需要在内存中存储会话信息,每个请求都包含足够的信息来验证用户。
- 可扩展性:因为JWT可以包含任何JSON数据,因此非常适合于传输各种类型的信息。
- 安全性:JWT可以使用密钥进行签名,确保发送方的身份和数据完整性。
JWT是如何将原始的JSON格式数据,转变为字符串的呢?
其实在生成JWT令牌时,会对JSON格式的数据进行一次编码:进行base64编码
Base64:是一种基于64个可打印的字符来表示二进制数据的编码方式。既然能编码,那也就意味着也能解码。所使用的64个字符分别是A到Z、a到z、 0- 9,一个加号,一个斜杠,加起来就是64个字符。任何数据经过base64编码之后,最终就会通过这64个字符来表示。当然还有一个符号,那就是等号。等号它是一个补位的符号
需要注意的是Base64是编码方式,而不是加密方式。
2. 生成和校验JWT令牌
简单介绍了JWT令牌以及JWT令牌的组成之后,接下来介绍基于Java代码如何生成和校验JWT令牌。
1 2 3 4 5 6
| <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>x.x.x</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| package camellia;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.junit.jupiter.api.Test;
import java.io.BufferedReader; import java.io.FileReader; import java.io.FileWriter; import java.util.Date; import java.util.HashMap; import java.util.Map;
public class JwtTest {
private static String token; private static final String SECRET_KEY = "Camellia24211";
@Test public void generateToken() { Map<String, Object> headerClaims = new HashMap<>(); headerClaims.put("typ", "JWT"); headerClaims.put("alg", "HS256"); Map<String, Object> payloadClaims = new HashMap<>(); payloadClaims.put("id", 24211); payloadClaims.put("name", "Camellia");
token = Jwts.builder() .setHeader(headerClaims) .setClaims(payloadClaims) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .setExpiration(new Date(System.currentTimeMillis() + 24 * 3600 * 1000)) .compact();
System.out.println(token); try (FileWriter fw = new FileWriter("src/main/resources/token.txt")) { fw.write(token); fw.flush(); } catch (Exception e) { e.printStackTrace(); } }
@Test public void verifyToken() { token = ""; try (BufferedReader br = new BufferedReader(new FileReader("src/main/resources/token.txt"))) { String line; while ((line = br.readLine()) != null) { token += line; } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println(token); }
Claims claims = Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody();
System.out.println(claims); } }
|
JWT工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| package camellia.utils;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import java.util.Date; import java.util.Map;
public class JwtUtils {
private static String signKey = "camellia"; private static Long expire = 43200000L;
public static String generateJwt(Map<String, Object> claims) { String jwt = Jwts.builder() .addClaims(claims) .signWith(SignatureAlgorithm.HS256, signKey) .setExpiration(new Date(System.currentTimeMillis() + expire)) .compact(); return jwt; }
public static Claims parseJWT(String jwt) { Claims claims = Jwts.parser() .setSigningKey(signKey) .parseClaimsJws(jwt) .getBody(); return claims; } }
|