1、引入jwt依賴
<!--jwt的依賴-->
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.18.3</version>
</dependency>
2、創建TokenUtils工具類
package com.pn.utils;import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.pn.entity.CurrentUser;
import com.pn.entity.User; //實體類
import com.pn.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import java.time.Duration;
import java.util.Date;/*** token工具類*/
@Component
public class TokenUtils {//注入redis模板@Autowiredprivate StringRedisTemplate stringRedisTemplate;Redis 0庫// @Autowired// @Qualifier("reactiveRedisTemplateDb0")// private ReactiveRedisTemplate<String, Object> redis;//注入配置文件中的warehouse.expire-time屬性 -- token的過期時間@Value("${warehouse.expire-time}")private Long expireTime;/*** 常量:*///token中存放用戶id對應的名字private static final String CLAIM_NAME_USERID = "CLAIM_NAME_USERID";//token中存放用戶名對應的名字private static final String CLAIM_NAME_USERCODE = "CLAIM_NAME_USERCODE";//token中存放用戶真實姓名對應的名字private static final String CLAIM_NAME_USERNAME = "CLAIM_NAME_USERNAME";// 真正的生成的jwt token的方法private String sign(User user) {String token = JWT.create().withClaim(CLAIM_NAME_USERID, user.getUserId()).withClaim(CLAIM_NAME_USERCODE, user.getUserCode()).withClaim(CLAIM_NAME_USERNAME, user.getUserName()).withIssuedAt(new Date())//發行時間.withExpiresAt(new Date(System.currentTimeMillis() + (expireTime * 1000L)))//有效時間.sign(Algorithm.HMAC256(user.getUserPwd()));//指定簽名return token;}/*** 方法一,jwt生成的 token存Redis,用Redis判斷是否存在* 將當前用戶信息以用戶密碼為密鑰生成token的方法*/public String loginSign(User user){//生成tokenString token = sign(user);//將token保存到redis中,并設置token在redis中的過期時間//stringRedisTemplate.opsForValue().set(token, token, Duration.ofSeconds(28800)).subscribe();stringRedisTemplate.opsForValue().set(token, token, expireTime);return token;}/*** 方法二,解析前端jwt生成的token進行校驗* 創建CurrentUser實體類接收* 從客戶端歸還的token中獲取用戶信息的方法*/public CurrentUser getCurrentUser(String token) {if(StringUtils.isEmpty(token)){throw new BusinessException("令牌為空,請登錄!");}//對token進行解碼,獲取解碼后的tokenDecodedJWT decodedJWT = null;try {decodedJWT = JWT.decode(token);} catch (JWTDecodeException e) {throw new BusinessException("令牌格式錯誤,請登錄!");}//從解碼后的token中獲取用戶信息并封裝到CurrentUser對象中返回int userId = decodedJWT.getClaim(CLAIM_NAME_USERID).asInt();//用戶賬號idString userCode = decodedJWT.getClaim(CLAIM_NAME_USERCODE).asString();//用戶賬號String userName = decodedJWT.getClaim(CLAIM_NAME_USERNAME).asString();//用戶姓名if(StringUtils.isEmpty(userCode) || StringUtils.isEmpty(userName)){throw new BusinessException("令牌缺失用戶信息,請登錄!");}return new CurrentUser(userId, userCode, userName);}}
3、使用
// 注入token對象@Autowiredprivate TokenUtils tokenUtils;@RequestMapping("/login")public String login(@RequestBody LoginUser loginUser) {// 生成tokenString token = tokenUtils.loginSign("傳入實體類");System.out.println(token);return token ;}