一、導入maven依賴
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
二、導入JWT工具類 (工具類)
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;public class JwtUtil {/*** secretKey jwt秘鑰*/private static String secretKey="xiaoxiaolichengxvyuan";/*** ttlMillis jwt過期時間(毫秒)* 設置有效期1天*/private static long ttlMillis=1000*3600*24;/*** 指定令牌名稱,前端需要在請求頭中攜帶tokenName*/public static String tokenName="Authorization";/*** 生成jwt* 使用Hs256算法, 私匙使用固定秘鑰 此秘鑰一定要保留好在服務端, 不能暴露出去, 否則sign就可以被偽造, 如果對接多個客戶端建議改造成多個* @param claims 設置的信息*/public static String createJWT( Map<String, Object> claims) {// 指定簽名的時候使用的簽名算法,也就是header那部分SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;// 生成JWT的時間long expMillis = System.currentTimeMillis() + ttlMillis;Date exp = new Date(expMillis);// 設置jwt的bodyJwtBuilder builder = Jwts.builder()// 如果有私有聲明,一定要先設置這個自己創建的私有的聲明,這個是給builder的claim賦值,一旦寫在標準的聲明賦值之后,就是覆蓋了那些標準的聲明的.setClaims(claims)// 設置簽名使用的簽名算法和簽名使用的秘鑰.signWith(signatureAlgorithm, secretKey.getBytes(StandardCharsets.UTF_8))// 設置過期時間.setExpiration(exp);return builder.compact();}/*** Token解密* @param token 加密后的token*/public static Claims parseJWT(String token) {// 得到DefaultJwtParserClaims claims = Jwts.parser()// 設置簽名的秘鑰.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))// 設置需要解析的jwt.parseClaimsJws(token).getBody();return claims;}
}
?
三、自定義JWT攔截器 (攔截器)
import com.example.testutils.utils.JwtUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class JwtInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){//判斷當前攔截到的是Controller的方法還是其他資源if (!(handler instanceof HandlerMethod)) {//當前攔截到的不是動態方法,直接放行return true;}//從請求頭獲取令牌String token=request.getHeader(JwtUtil.tokenName);try {//判斷是否攜帶令牌if (StringUtils.isEmpty(token)){throw new Exception("未攜帶JWT令牌");}//判斷令牌是否有效if (JwtUtil.parseJWT(token)==null){throw new Exception("JWT令牌有誤");}}catch (Exception e){//出現異常,攔截,設置狀態碼為401response.setStatus(401);return false;}return true;}
}
四、將攔截器加入配置(配置類)
import com.example.testutils.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**")//設置不攔截的請求路徑,如登錄接口不需要攔截等.excludePathPatterns("/login")//我使用了Knife4j測試文檔,如果你沒使用,可以不配置下面這行.excludePathPatterns("/doc.html","/swagger-resources");}
}