提示:以下内容为个人学习所整理,内容来源于网络,仅供参考
前言
提示:
提示:以下是本篇文章正文内容,下面案例可供参考
一、JWT是什么?
全称是JSON Web Token,官网地址:https://jwt.io/
二、使用步骤
1.引Maven依赖
代码如下(示例):
<!--jwt依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.使用jwt获取token
代码如下(示例):
/**
* 根据荷载生成JWT的token
*/
@Test
public void getToken() {
Map<String, Object> claims = new HashMap<>();
claims.put("sub", "zhangsan");
claims.put("created", new Date());
String token = Jwts.builder()
// 设置载荷key value
.setClaims(claims)
// 设置失效时间
.setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
// 设置签名
.signWith(SignatureAlgorithm.HS512, "secret")
.compact();
System.out.println("获取token:"+ token);
}
打印结果:
获取token:eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ6aGFuZ3NhbiIsImNyZWF0ZWQiOjE2NzMwODQxODUyNzAsImV4cCI6MTY3MzE3MDU4NX0.y8uF1GqLaFPeNa0TIIjwffBX0QEVbIQjijOywoe8jRWCJ0Vdo3AGM-BIPo_56UNqTnnwaaxdntYccXVo6RywHg
3.从token中获取载荷信息
/**
* 从token中获取JWT中的载荷
*/
@Test
public void getClaimsFromToken() {
String token = "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ6aGFuZ3NhbiIsImNyZWF0ZWQiOjE2NzMwODQxODUyNzAsImV4cCI6MTY3MzE3MDU4NX0.y8uF1GqLaFPeNa0TIIjwffBX0QEVbIQjijOywoe8jRWCJ0Vdo3AGM-BIPo_56UNqTnnwaaxdntYccXVo6RywHg";
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey("secret")
.parseClaimsJws(token)
.getBody();
System.out.println("打印载荷:"+ claims + " 过期时间:" + claims.getExpiration() + " sub:" + claims.getSubject());
} catch (Exception e) {
LOGGER.info("JWT格式验证失败:{}",token);
}
}
打印结果:
打印载荷:{sub=zhangsan, created=1673084185270, exp=1673170585} 过期时间:Sun Jan 08 17:36:25 CST 2023 sub:zhangsan
这里载荷信息 为明文,不要存储密码
通用的JwtToken工具类
package org.example.config.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Created with IntelliJ IDEA.
*
* @Author: 你的名字
* @Date: 2023/01/06/18:03
* @Description:
* 相关方法说明
*
* generateToken(Map<String, Object> claims)
* 根据负载生成JWT的token
*
* getClaimsFromToken(String token)
* 从token中获取JWT中的负载
*
* generateExpirationDate()
* 生成token的过期时间
*
* getUserNameFromToken(String token)
* 从token中获取登录用户名*
*
* validateToken(String token, UserDetails userDetails)
* 验证token是否还有效*
*
* isTokenExpired(String token)
* 判断token是否已经失效
*
* getExpiredDateFromToken(String token)
* 从token中获取过期时间
*
* generateToken(UserDetails userDetails)
* 根据用户信息生成token*
*
* canRefresh(String token)
* 判断token是否可以被刷新
*
* refreshToken(String token)
* 刷新token
* 原文链接:https://blog.csdn.net/qq_41028058/article/details/121394361
*/
@Component
public class JwtTokenUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
private static final String CLAIM_KEY_USERNAME = "sub";
private static final String CLAIM_KEY_CREATED = "created";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
/**
* 根据用户信息生成token
*/
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
/**
* 根据荷载生成JWT的token
*/
private String generateToken(Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
/**
* 从token中获取JWT中的负载
*/
private Claims getClaimsFromToken(String token) {
Claims claims = null;
try {
claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
LOGGER.info("JWT格式验证失败:{}",token);
}
return claims;
}
/**
* 生成token的过期时间
*/
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis() + expiration * 1000);
}
/**
* 从token中获取登录用户名
*/
public String getUserNameFromToken(String token) {
String username;
try {
Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
/**
* 验证token是否还有效
*
* @param token 客户端传入的token
* @param userDetails 从数据库中查询出来的用户信息
*/
public boolean validateToken(String token, UserDetails userDetails) {
String username = getUserNameFromToken(token);
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
/**
* 判断token是否已经失效
*/
private boolean isTokenExpired(String token) {
Date expiredDate = getExpiredDateFromToken(token);
return expiredDate.before(new Date());
}
/**
* 从token中获取过期时间
*/
private Date getExpiredDateFromToken(String token) {
Claims claims = getClaimsFromToken(token);
return claims.getExpiration();
}
/**
* 判断token是否可以被刷新
*/
public boolean canRefresh(String token) {
return !isTokenExpired(token);
}
/**
* 刷新token
*/
public String refreshToken(String token) {
Claims claims = getClaimsFromToken(token);
claims.put(CLAIM_KEY_CREATED, new Date());
return generateToken(claims);
}
}
配置信息:
jwt:
# jwt存储的请求头
tokenHeader: Authorization
# jwt加解密使用的秘钥
secret: yeb-secret
# jwt的超期限时间(60*60*24)
expiration: 604800
# jwt负载中拿到开头
tokenHead: Bearer
总结
参考博客
链接: https://blog.csdn.net/weixin_45070175/article/details/118559272