赞
踩
网关,即网络的关口,当一个网络传输到另一个网络时就需要经过网关来实现
以及
SpringCloudGateWay:
基于Spring的WebFlux技术,完全支持响应式编程,吞吐能力更强
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
gateway: routes: - id: item # 路由规则id,自定义,唯一 uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表 predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务 - Path=/items/**,/search/** # 这里是以请求路径作为判断规则 - id: cart uri: lb://cart-service predicates: - Path=/carts/** - id: user uri: lb://user-service predicates: - Path=/users/**,/addresses/** - id: trade uri: lb://trade-service predicates: - Path=/orders/** - id: pay uri: lb://pay-service predicates: - Path=/pay-orders/**
网关过滤器流程如下所示
请求进入网关由HandlerMapping判断,根据规则路由交给WebHandler处理
WebHandler加载路由下需要执行的过滤器链,按顺序一一执行
Filter分为pre和post两部分,分别在微服务之前和之后执行
所有pre过滤器执行完成后请求就会发送到微服务
GatewayFilter
:路由过滤器,作用范围比较灵活,可以是任意指定的路由Route
GlobalFilter
:全局过滤器,作用范围是所有路由,不可配置
spring:
cloud:
gateway:
routes:
- id: test_route
uri: lb://test-service
predicates:
-Path=/test/**
filters:
- AddRequestHeader=key, value # 逗号之前是请求头的key,逗号之后是value
将内置的AddRequestHeader过滤器作用在对应的路由中,作用是给请求添加一个请求头传递到下游的微服务中
spring:
cloud:
gateway:
default-filters: # default-filters下的过滤器可以作用于所有路由
- AddRequestHeader=key, value
routes:
- id: test_route
uri: lb://test-service
predicates:
-Path=/test/**
将过滤器置于default-filters下可以生效于所有路由
并不是直接使用内置的GatewayFilter而是实现AbstractGatewayFilterFactory
@Component public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> { @Override public GatewayFilter apply(Object config) { return new GatewayFilter() { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 获取请求 ServerHttpRequest request = exchange.getRequest(); // 编写过滤器逻辑 System.out.println("过滤器执行了"); // 放行 return chain.filter(exchange); } }; } }
重写过滤器内部的apply方法
在apply方法内部返回一个gatewayFilter对象,并重写其中的filter规则作为业务逻辑
使用时:直接和之前一样在路由配置中使用即可
spring:
cloud:
gateway:
default-filters:
- PrintAny # 此处直接以自定义的GatewayFilterFactory类名称前缀类声明过滤器
还可以通过在自定义网关中配置内部配置类和重写getConfigClass来自定义网关参数
globalFilter的自定义比较简单,也无法设置动态参数
直接通过实现GlobalFilter接口即可
重写filter编写拦截逻辑
重写getOrder规定过滤器的执行顺序
@Component public class PrintAnyGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 编写过滤器逻辑 System.out.println("未登录,无法访问"); // 放行 // return chain.filter(exchange); // 拦截 ServerHttpResponse response = exchange.getResponse(); response.setRawStatusCode(401); return response.setComplete(); } @Override public int getOrder() { // 过滤器执行顺序,值越小,优先级越高 return 0; } }
package com.hmall.gateway.filter; import com.hmall.common.exception.UnauthorizedException; import com.hmall.common.utils.CollUtils; import com.hmall.gateway.config.AuthProperties; import com.hmall.gateway.util.JwtTool; import lombok.RequiredArgsConstructor; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.util.List; @Component @RequiredArgsConstructor @EnableConfigurationProperties(AuthProperties.class) public class AuthGlobalFilter implements GlobalFilter, Ordered { private final JwtTool jwtTool; private final AuthProperties authProperties; private final AntPathMatcher antPathMatcher = new AntPathMatcher(); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取Request ServerHttpRequest request = exchange.getRequest(); // 2.判断是否不需要拦截 if(isExclude(request.getPath().toString())){ // 无需拦截,直接放行 return chain.filter(exchange); } // 3.获取请求头中的token String token = null; List<String> headers = request.getHeaders().get("authorization"); if (!CollUtils.isEmpty(headers)) { token = headers.get(0); } // 4.校验并解析token Long userId = null; try { userId = jwtTool.parseToken(token); } catch (UnauthorizedException e) { // 如果无效,拦截 ServerHttpResponse response = exchange.getResponse(); response.setRawStatusCode(401); return response.setComplete(); } // TODO 5.如果有效,传递用户信息 System.out.println("userId = " + userId); // 6.放行 return chain.filter(exchange); } private boolean isExclude(String antPath) { for (String pathPattern : authProperties.getExcludePaths()) { if(antPathMatcher.match(pathPattern, antPath)){ return true; } } return false; } @Override public int getOrder() { return 0; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。