一、JwtUtil 工具類
package com.changgou.system.utils;
/**
* @author :lijunxuan
* @date :Created in 2019/7/11 17:14
* @description :
* @version: 1.0
*/
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
/**
* JWT工具類
*/
public class JwtUtil {
//有效期爲
public static final Long JWT_TTL = 3600000L;// 60 * 60 *1000 一個小時
//設置祕鑰明文
public static final String JWT_KEY = "william";
/**
* 創建token
* @param id
* @param subject
* @param ttlMillis
* @return
*/
public static String createJWT(String id, String subject, Long ttlMillis) {
//定義jwt簽名的算法
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//當前時間
long nowMillis = System.currentTimeMillis();
//將當前時間轉換日期類型
Date now = new Date(nowMillis);
//將當前時間+超時時間
if(ttlMillis==null){
ttlMillis=JwtUtil.JWT_TTL;
}
long expMillis = nowMillis + ttlMillis;
//將時間定義爲date類型
Date expDate = new Date(expMillis);
//獲取簽名時候使用的密鑰
SecretKey secretKey = generalKey();
JwtBuilder builder = Jwts.builder()
.setId(id) //唯一的ID
.setSubject(subject) // 主題 可以是JSON數據
.setIssuer("admin") // 簽發者
.setIssuedAt(now) // 簽發時間
.signWith(signatureAlgorithm, secretKey) //使用HS256對稱加密算法簽名, 第二個參數爲祕鑰
.setExpiration(expDate);// 設置過期時間
return builder.compact();
}
/**
* 生成加密後的祕鑰 secretKey
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
}
二、創建過濾器,用於token驗證
package com.william.filter;
import com.william.util.JwtUtil;
import io.jsonwebtoken.Jwts;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author :lijunxuan
* @date :Created in 2019/7/11 17:39
* @description :
* @version: 1.0
*/
/**
* 鑑權過濾器
* 判斷用戶是否有權限訪問
*/
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
//請求頭中的令牌常量
public final static String TOKEN = "token";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.獲取請求
ServerHttpRequest request = exchange.getRequest();
//2.獲取響應
ServerHttpResponse response = exchange.getResponse();
//3.判斷用戶是否訪問的爲登錄路徑,如果是登錄路徑則放行
if (request.getURI().getPath().contains("/admin/login")){
return chain.filter(exchange);
}
//4. 獲取請求頭中的令牌
HttpHeaders headers = request.getHeaders();
String token = headers.getFirst(TOKEN);
//5. 如果請求頭中的令牌爲空, 則返回錯誤狀態碼
if (StringUtils.isEmpty(token)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//6. 解析請求頭中的jwt令牌
try {
JwtUtil.parseJWT(token);
} catch (Exception e) {
//7. 如果解析出錯, 說明令牌過期或者被篡改, 返回狀態碼
e.printStackTrace();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
//8. 如果解析正常則放行
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 3;
}
}
測試結果