前言
接上次,整合SpringSecurity后,我们进行jwt的整合
JWT令牌颁发
导jar包
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.3.0</version>
</dependency>
创建处理JWT令牌的工具类
创建utils包,与JwtUtils类
根据用户信息创建Jwt令牌
由于我们的JWT令牌需要在根据用户信息创建,所以我们要在Spring Security登录成功里面的处理器进行创建。
那用户信息怎么读呢?
在Spring Security中,认证成功后,会将用户的信息封装成Authentication对象,并存储在SecurityContextHolder中。
所以我们可以通过authentication.getPrincipal(),authentication.getPrincipal()是用于获取当前认证成功的用户对象。
authentication.getPrincipal()返回的是一个Principal对象,用户信息实际上是存储在该对象中的。在大多数情况下,Principal对象会实现UserDetails接口,因此可以将其强制转换为UserDetails类型,以方便获取用户的详细信息,如用户名、过期时间、角色等。
正式创建Jwt令牌
我们回到JwtUtils工具类中,因为我们用户信息是UserDetails类型,所以传入的对象也是这个类型,注意我们UserDetails里面是没有id的,而且有可能里面是存储的是邮箱不是用户名,所以id和用户名要另外传入。
密钥与过期时间我们放在配置类中读取,过期时间不要太长,要不然就是永久的了
@Value("${spring.security.jwt.key}")
private String key;
@Value("${spring.security.jwt.expire}")
private int expire;
public String createJwt(UserDetails user, String username, int userId) {
Algorithm algorithm = Algorithm.HMAC256(key); // 使用HMAC256算法生成JWT的签名
Date expire = this.expireTime(); // 设置JWT的过期时间
return JWT.create()
.withJWTId(UUID.randomUUID().toString()) // 设置JWT的唯一标识
.withClaim("id", userId) // 设置用户id
.withClaim("name", username) // 设置用户名
.withClaim("authorities", user.getAuthorities() // 设置用户权限,将他转为集合形式
.stream()
.map(GrantedAuthority::getAuthority)
.toList())
.withExpiresAt(expire) // 设置JWT的过期时间
.withIssuedAt(new Date()) // 设置JWT的发布时间
.sign(algorithm); // 使用算法进行签名
}
/**
* 根据配置快速计算过期时间
* @return 过期时间
*/
public Date expireTime(){
// 创建一个Calendar对象
Calendar calendar = Calendar.getInstance();
// 将当前时间加上过期时间的小时数
calendar.add(Calendar.HOUR, expire);
// 返回计算后的过期时间
return calendar.getTime();
}