引入依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
我和nacos整合了 引入了下面的依賴
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.1.4.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.1.4.RELEASE</version> </dependency>
如果網關有時候請求超時或者卡頓 ,可以在主啟動類中加入
public static void main(String[] args) { System.setProperty(ReactorNetty.NATIVE,"false"); System.setProperty(ReactorNetty.IO_WORKER_COUNT, "6"); System.setProperty(ReactorNetty.IO_SELECT_COUNT, "6"); SpringApplication.run(GatewayApplication.class, args); }
統一鑒權過濾器
AuthFilter.java
import com.alibaba.fastjson.JSON; import com.kotei.gatewayweb.apiResult.ApiResult; import com.kotei.gatewayweb.config.properties.IgnoreWhiteProperties; import com.kotei.gatewayweb.config.redis.RedisUtils; import com.kotei.gatewayweb.utils.JWTUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; 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.DataBufferFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.List; /** * 網關鑒權 * * @author . */ @Component public class AuthFilter implements GlobalFilter, Ordered { private static final Logger log = LoggerFactory.getLogger(AuthFilter.class); @Autowired private RedisUtils redisUtils; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String url = exchange.getRequest().getURI().getPath();// 跳過不需要驗證的路徑 配置文件里自己添加 list集合格式即可 ,這里是偽代碼 所以沒有這個類 if (matches(url, ignoreWhite.getWhites())) { log.info(">>>>>>>>跳過該請求驗證:{}",url); return chain.filter(exchange); } //這是請求接口中header的token參數值 String token = exchange.getRequest().getHeaders().getFirst("token"); if (token == null || !redisUtils.exists(token)) { return setUnauthorizedResponse(exchange, "token信息不存在"); } //驗證token是否正確 根據自己的來 boolean validateJWT = JWTUtils.validateJWT(token); if (!validateJWT) { return setUnauthorizedResponse(exchange, "令牌驗證失敗"); } log.info(">>>>>>>>>>>認證執行完成 {}",url); return chain.filter(exchange); } /** * 查找指定字符串是否匹配指定字符串列表中的任意一個字符串 * * @param str 指定字符串 * @param strs 需要檢查的字符串數組 * @return 是否匹配 */ public static boolean matches(String str, List<String> strs) { if (StringUtils.isEmpty(str) || CollectionUtils.isEmpty(strs)) { return false; } for (String pattern : strs) { if (isMatch(pattern,str)) { return true; } } return false; } /** * 判斷url是否與規則配置: * ? 表示單個字符; * * 表示一層路徑內的任意字符串,不可跨層級; * ** 表示任意層路徑; * * @param pattern 匹配規則 * @param url 需要匹配的url * @return */ public static boolean isMatch(String pattern, String url) { AntPathMatcher matcher = new AntPathMatcher(); return matcher.match(pattern, url); }
//返回錯誤信息 private Mono<Void> setUnauthorizedResponse(ServerWebExchange exchange, String msg) { ServerHttpResponse response = exchange.getResponse(); response.getHeaders().setContentType(MediaType.APPLICATION_JSON); response.setStatusCode(HttpStatus.OK); log.error("[鑒權異常處理]請求路徑:{}", exchange.getRequest().getPath()); return response.writeWith(Mono.fromSupplier(() -> { DataBufferFactory bufferFactory = response.bufferFactory(); return bufferFactory.wrap(JSON.toJSONBytes(new ApiResult<>().failure(msg))); })); } @Override public int getOrder() { return -200; } }
官方文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/
配置示例(以下是整合nacos的寫法,主要是routes部分)
spring:
cloud:
gateway:
discovery:
locator:
enabled: true #讓gateway可以發現nacos中的其他微服務, 進行路由轉發
routes:
- id: api
uri: lb://api-service
predicates:
- Path=/api/**
id:唯一標識,必須唯一
url:轉發的服務 lb 是因為使用了 注冊中心
predicates 斷言 ,表示符合規則就進行轉發
-path 表示 匹配該請求/api/**規則 就轉發到 http://api-service/api/** 去
請求路徑截取
spring:
cloud:
gateway:
routes:
- id: nameRoot
uri: https://nameservice
predicates:
- Path=/name/api/**
filters:
- StripPrefix=1
使用 StripPrefix 會把 /name/api/** 轉發到 https://nameservice/api/**
這里的“1”表示截去的前面的 /name
如果是“2”就表示截去前面的 “/name/api”