目录
1.什么是JWT令牌
2.令牌的优缺点
优点:
1.解决了集群环境下的认证问题
2.减轻服务器的存储压⼒(⽆需在服务器端存储)
缺点:
需要⾃⼰实现(包括令牌的⽣成, 令牌的传递, 令牌的校验)
JSON Web Token(JWT)是⼀个开放的⾏业标准(RFC 7519), ⽤于客⼾端和服务器之间传递安全可靠的信息.
1.Header(头部)头部包括令牌的类型(即JWT)及使⽤的哈希算法(如HMAC SHA256或RSA。2.Payload(负载)负载部分是存放有效信息的地⽅, ⾥⾯是⼀些⾃定义内容, 也可以存在jwt提供的现场字段, ⽐如 exp(过期时间戳)等。3. Signature(签名) 此部分⽤于防⽌jwt内容被篡改, 确保安全性
2 .JWT令牌⽣成和校验
2.1JWT令牌⽣成
1.引⼊JWT令牌的依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
2.使⽤Jar包中提供的API来完成JWT令牌的⽣成
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.springframework.boot.test.context.SpringBootTest;
import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JWTUtilsTest {
//过期毫秒时⻓ 30分钟
public static final long Expiration = 30 * 60 * 1000;
//密钥
private static final String secretString = "dVnsmy+SIX6pNptQdeclDSJ26EMSPEIhvZYKBTTug4k=";
//⽣成安全密钥
private static final SecretKey KEY = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));
public void genJwt() {
//⾃定义信息
Map<String, Object> claim = new HashMap<>();
claim.put("id", 1);
claim.put("username", "zhangsan");
String jwt = Jwts.builder()
.setClaims(claim) //⾃定义内容(负载)
.setIssuedAt(new Date())// 设置签发时间
.setExpiration(new Date(System.currentTimeMillis() +
Expiration)) //设置过期时间
.signWith(KEY) //签名算法
.compact();
System.out.println(jwt);
}
}
调用genJwt()后的现象:

这个是打印的token,之后就校验这个token。
eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6aGFuZ3NhbiIsImlhdCI6MTczMjYwNTU1MiwiZXhwIjoxNzMyNjA3MzUyfQ.gEPLGGWlOlw4lUYjvA-rhE5DqhKtdpHmP35gpzooYUk

注意: 对于密钥有⻓度和内容有要求, 建议使⽤
/**⽣成密钥*/
public void genKey() {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
String secretString = Encoders.BASE64.encode(key.getEncoded());
System.out.println(secretString);
}
Base64是编码⽅式,⽽不是加密⽅式
调用genKey()后的现象:

2.2JWT令牌的校验
/**
* 校验token
* Claims 为 null 表示校验失败
*/
@Test
public void parseToken() {
String token = "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6aGFuZ3NhbiIsImlhdCI6MTczMjYw" +
"NTU1MiwiZXhwIjoxNzMyNjA3MzUyfQ.gEPLGGWlOlw4lUYjvA-rhE5DqhKtdpHmP35gpzooYUk";
JwtParser build = Jwts.parserBuilder().setSigningKey(KEY).build();
Claims claims = null;
try {
claims = build.parseClaimsJws(token).getBody();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(claims);
}
}
令牌解析后, 我们可以看到⾥⾯存储的信息,如果在解析的过程当中没有报错,就说明解析成功了
调用parseToken()后的现象:
![]()
1.令牌解析时, 也会进⾏时间有效性的校验, 如果令牌过期了, 解析也会失败
2.修改令牌中的任何⼀个字符, 都会校验失败, 所以令牌⽆法篡改
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞 ![]()

1184

被折叠的 条评论
为什么被折叠?



