本文主要介绍如何在springcloud中配置gateway网关的全局过滤器,实现对全部路由访问请求的拦截、验证、鉴权等。本例使用的springcloud版本为:2021.0.3,springboot版本为:2.6.8。
1、创建gateway网关项目
打开idea新建项目,选择maven,创建springboot项目gateway-6001。
2、pom文件配置
在项目pom中引入spring-cloud-starter-netflix-eureka-client和spring-cloud-starter-gateway依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
3、application.yml文件配置
在项目resources文件夹下创建application.yml文件,并按如下内容进行配置:
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
fetch-registry: true
instance:
instance-id: gateway-${server.port}
prefer-ip-address: true
spring:
application:
name: gateway
cloud:
gateway:
routes: # 网关路由配置
- id: payment # 路由id,自定义,只要唯一即可
uri: lb://PAYMENT-SERVER # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/payment/** # 这个是按照路径匹配,只要以/payment/开头就符合要求
其中spring.cloud.gateway下未网关路由的配置,id为路由id需要唯一不重复;uri为路由目标地址,lb + 服务名称可以使用负责均衡访问服务;predicates为路由断言;当前配置表示只要以/paymnet/开发的访问就会转发到PAYMENT-SERVER服务。
4、主应用类配置
在项目src/main/java下创建主应用类 GatewayApplication.java,添加注解@EnableEurekaClient、@SpringBootApplication。
@EnableEurekaClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
本文主要介绍如何在springcloud中配置gateway网关的全局过滤器,实现对全部路由访问请求的拦截、验证、鉴权等。本例使用的springcloud版本为:2021.0.3,springboot版本为:2.6.8。
1、创建gateway网关项目
打开idea新建项目,选择maven,创建springboot项目gateway-6001。
2、pom文件配置
在项目pom中引入spring-cloud-starter-netflix-eureka-client和spring-cloud-starter-gateway依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
3、application.yml文件配置
在项目resources文件夹下创建application.yml文件,并按如下内容进行配置:
server:
port: 6001
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
fetch-registry: true
instance:
instance-id: gateway-${server.port}
prefer-ip-address: true
spring:
application:
name: gateway
cloud:
gateway:
routes: # 网关路由配置
- id: payment # 路由id,自定义,只要唯一即可
uri: lb://PAYMENT-SERVER # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
- Path=/payment/** # 这个是按照路径匹配,只要以/payment/开头就符合要求
其中spring.cloud.gateway下未网关路由的配置,id为路由id需要唯一不重复;uri为路由目标地址,lb + 服务名称可以使用负责均衡访问服务;predicates为路由断言;当前配置表示只要以/paymnet/开发的访问就会转发到PAYMENT-SERVER服务。
4、主应用类配置
在项目src/main/java下创建主应用类 GatewayApplication.java,添加注解@EnableEurekaClient、@SpringBootApplication。
@EnableEurekaClient
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
5、全局过滤器配置
在config文件夹下创建配置类GateWayConfig ,用于注解@bean返回全局过滤器CustomGlobalFilter。
@Configuration
public class GateWayConfig {
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
}
在filter文件夹下创建全局过滤器CustomGlobalFilter,如果验证通过则调用chain.filter(exchange)执行下一过滤器。如果验证失败,则直接返回响应内容。getOrder返回值用于设置各个过滤器的执行顺序,数值越小优先级越高。
@Component
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if(exchange.getRequest().getQueryParams().getFirst("token") == null){
ServerHttpResponse response = exchange.getResponse();
JSONObject res = new JSONObject();
res.put("status","-1");
res.put("msg","need login");
byte[] datas = JSONObject.toJSONBytes(res);
DataBuffer buffer = response.bufferFactory().wrap(datas);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
log.warn("无效访问");
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
}
public int getOrder() {
return 0;
}
}
6、测试验证
同时启动并运行项目eueka-server-7001、payment-8001、payment-8002、gateway-6001。然后在postman中进行接口调用测试。
通过访问http://127.0.0.1:6001/payment/get/1时,由于没有传递token数据所以拦截器验证失败,返回错误信息。
通过访问http://127.0.0.1:6001/payment/get/1?token=abc时,则可以正常返回数据。