JWT练习
一、导入依赖
在pom文件中加入如下依赖
<!-- jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- 加上这个依赖spring-boot-configuration-processor在JwtUtils类中就不报错Spring Boot Configuration Annotation Processor not configured
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
二、修改配置文件
在application.properties中添加如下内容
################################# 自定义属性 #################################
#jwt配置
#密钥
jwt.secret=com.jiekki
#过期时间(30分钟)
jwt.expiration=1800000
三、实体类编写
这里随便弄了个Student类,实际开发中需要用UserDetails类
package com.example.jwtdemo;
public class Student {
private String stuId;
private String stuName;
private int age;
public Student() {
}
public Student(String stuId, String stuName, int age) {
this.stuId = stuId;
this.stuName = stuName;
this.age = age;
}
public String getStuId() {
return stuId;
}
public void setStuId(String stuId) {
this.stuId = stuId;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
四、编写JwtUtils工具类
package com.example.jwtdemo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* jwt工具类
*/
@Component
@ConfigurationProperties("jwt")//此注解会将application.properties中的jwt.的属性配置对应到JwtUtils类中的成员变量
public class JwtUtils {
//密钥
private String secret;
// 过期时间 毫秒
private Long expiration;
/**
* 从数据声明生成令牌
* @param claims 数据声明
* @return 令牌
*/
private String generateToken(Map<String, Object> claims) {
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return
Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact();
}
/**
* 从令牌中获取数据声明
* @param token 令牌
* @return 数据声明
*/
public Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims =
Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
/**
* 生成令牌
*
* @param student 学生对象
* @return 令牌
*/
public String generateToken(Student student) {
Map<String, Object> claims = new HashMap<>(2);
claims.put(Claims.SUBJECT, student.getStuName());
claims.put("age", student.getAge());
return generateToken(claims);
}
/**
* 从令牌中获取用户名
*
* @param token 令牌
* @return 用户名
*/
public String getUsernameFromToken(String token) {
String stuName;
try {
Claims claims = getClaimsFromToken(token);
stuName = claims.getSubject();
} catch (Exception e) {
stuName = null;
}
return stuName;
}
/**
* 判断令牌是否过期
*
* @param token 令牌
* @return 是否过期
*/
public Boolean isTokenExpired(String token) {
Claims claims = getClaimsFromToken(token);
Date expiration = claims.getExpiration();
return expiration.before(new Date());
}
/**
* 刷新令牌
* @param token 原令牌
* @return 新令牌
*/
public String refreshToken(String token) {
String refreshedToken;
try {
Claims claims = getClaimsFromToken(token);
claims.put(Claims.ISSUED_AT, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
/**
* 验证令牌
*
* @param token 令牌
* @param student 学生对象
* @return 是否有效
*/
public Boolean validateToken(String token, Student student) {
//从token中取出学生名
String username = getUsernameFromToken(token);
//如果从token中取出的学生名与传入的学生对象的名称一致,并且token令牌没有过期,那么就返回true
return (username.equals(student.getStuName()) && !isTokenExpired(token));
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public Long getExpiration() {
return expiration;
}
public void setExpiration(Long expiration) {
this.expiration = expiration;
}
}
五、测试
package com.example.jwtdemo;
import io.jsonwebtoken.Claims;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class JwtdemoApplicationTests {
@Autowired
JwtUtils jwtUtils;
@Test
void 测试生成token() {
Student student=new Student("1723111028","jiekki",13);
String token = jwtUtils.generateToken(student);
System.out.println(token);
}
@Test
void 测试获取用户名(){
String token="eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2ODEzMDk0NTEsInN1YiI6ImppZWtraSIsImFnZSI6MTN9.2MVhaxzjczrSfLvoM-QFeX1w5L1NyPYtea3CffIZjxOckhk6nx7cHp5UJae6k5B4kuMqYhnWcQ139RFeRYCI4Q";
String username = jwtUtils.getUsernameFromToken(token);
System.out.println(username);
}
@Test
void 从令牌中获取数据声明(){
String token="eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2ODEzMDk0NTEsInN1YiI6ImppZWtraSIsImFnZSI6MTN9.2MVhaxzjczrSfLvoM-QFeX1w5L1NyPYtea3CffIZjxOckhk6nx7cHp5UJae6k5B4kuMqYhnWcQ139RFeRYCI4Q";
Claims claims = jwtUtils.getClaimsFromToken(token);
String stuName = claims.get("sub",String.class);
int age = claims.get("age",Integer.class);
System.out.println(stuName);
System.out.println(age);
System.out.println(claims);
}
}