前言
接上次,整合SpringSecurity后,我们进行jwt的整合
JWT令牌颁发
导jar包
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>4.3.0</version> </dependency>
创建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(); }