全局过滤器配置
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
过滤器
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Value("#{'${gateway.excludedUrls}'.split(',')}")
private List<String> excludedUrls;
@Value("${gateway.secret}")
private String secret;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse response = exchange.getResponse();
String path = exchange.getRequest().getURI().getPath();
if (excludedUrls.contains(path)){
return chain.filter(exchange);
}
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (StringUtils.isNotEmpty(token)){
JWTUtil.VerifyResult verifyResult = JWTUtil.verifyJwt(token, secret);
if (verifyResult.isValidate()){
return chain.filter(exchange);
}else{
Map<String,Object> responseData = Maps.newHashMap();
responseData.put("code",verifyResult.getCode());
responseData.put("message","验证失败");
return responseError(response,responseData);
}
}else{
Map<String,Object> responseData = Maps.newHashMap();
responseData.put("code",401);
responseData.put("message","非法请求");
responseData.put("cause","token is empty");
return responseError(response,responseData);
}
}
private Mono<Void> responseError(ServerHttpResponse response, Map<String, Object> responseData) {
ObjectMapper objectMapper = new ObjectMapper();
byte[] data = new byte[0];
try{
data = objectMapper.writeValueAsBytes(responseData);
}catch (Exception e){
e.printStackTrace();
}
DataBuffer buffer = response.bufferFactory().wrap(data);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type","application/json;charset=utf-8");
return response.writeWith(Mono.just(buffer));
}
@Override
public int getOrder() {
return 0;
}
}
JWT工具类
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class JWTUtil{
public static String createJWTByObj(Map<String, Object> tokenMap, String secret) throws IOException {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
SecretKey secretKey = generalKey(secret);
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = LocalDateTime.now().plusDays(3).atZone(zoneId);
JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
.setId("myApp")
.setIssuedAt(Date.from(zdt.toInstant()))
.setHeaderParam("alg", "HS256")
.addClaims(tokenMap)
.setExpiration(Date.from(zdt.toInstant()))
.signWith(signatureAlgorithm, secretKey);
return builder.compact();
}
public static VerifyResult verifyJwt(String token, String secret) {
SecretKey key = generalKey(secret);
try {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = LocalDateTime.now().atZone(zoneId);
Jwt jwt = Jwts.parser()
.setSigningKey(key)
.parse(token);
Date date = ((Claims) jwt.getBody()).getExpiration();
if (date == null) {
return new VerifyResult(false, 5002);
}
LocalDateTime expires = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
if (expires.isBefore(LocalDateTime.now())) {
return new VerifyResult(false, 5001);
}
return new VerifyResult(true, 200);
} catch (Exception e) {
e.printStackTrace();
return new VerifyResult(false, 5002);
}
}
public static Map<String,Object> decode(String token) throws IOException {
String bodyData = token.split("\\.")[1];
String bodyStr = new String(Base64.decodeBase64(bodyData),"UTF-8");
return JSON.parseObject(bodyStr,Map.class);
}
private static SecretKey generalKey(String jwtSecret) {
String stringKey = jwtSecret;
byte[] encodedKey = Base64.decodeBase64(stringKey);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
@Data
public static class VerifyResult{
private boolean isValidate;
private int code;
private Map<String,Object> tokenMap;
public VerifyResult(boolean isValidate, int code) {
this.isValidate = isValidate;
this.code = code;
System.out.println("1111");
}
}
}