SpringBoot简单整合Gateway网关
引入依赖
<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”
-----------------------有任何问题可以在评论区评论,也可以私信我,我看到的话会进行回复,欢迎大家指教------------------------
(蓝奏云官网有些地址失效了,需要把请求地址lanzous改成lanzoux才可以)