目录
三、路由断言工厂Route Predicate Factory
一、网关的功能和作用
1.网关的功能
(1)身份验证和权限校验
(2)服务路由、负载均衡
(3)请求限流
2.网关的作用
(1)对用户请求做身份认证、权限校验
(2)将用户请求路由到微服务,并实现负载均衡
(3)对用户请求做限流
二、搭建网关服务
1.添加依赖
创建新的moudel,添加SringCloudGateway和nacos的服务发现依赖
<!--nacos服务注册发现依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--网关gateway依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
2.添加配置
在application.yml文件中添以下配置
server: port: 10010 #端口号 logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS spring: application: name: gateway #服务名 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: - id: user-service # 路由标示,必须唯一 uri: lb://userservice # 路由的目标地址 predicates: # 路由断言,判断请求是否符合规则 - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合 - id: order-service uri: lb://orderservice predicates: - Path=/order/**
3.小结
搭建网关服务步骤:创建项目,引入依赖,在application.yml中配置服基本信息、nacos地址、路由。
三、路由断言工厂Route Predicate Factory
网关路由配置包含一下基本信息:
路由id:路由唯一标识
uri:路由目标地址,支持lb(负载均衡)和http(固定地址)
predicates: 路由断言,判断请求是否符合规则
filters:路由过滤器,处理请求或响应
Spring提供了11中基本的predicate工厂:
PredicateFactory的作用读取用户定义的断言条件,对请求做出判断
四、路由过滤器GateFliter
GatewayFilter 是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理:
给所有进入 userservice 的请求添加一个请求头: Truth=itcast is freaking awesome!
public class UserController {
@Autowired
private UserService userService;
/**
* 路径: /user/110
*
* @param id 用户id
* @return 用户
*/
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,
@RequestHeader(value = "Truth", required = false) String truth) {
System.out.println("truth: " + truth);
return userService.queryById(id);
}
}
实现方式:在 gateway 中修改 application.yml 文件,给 userservice 的路由添加过滤器:
server: port: 10010 logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS spring: application: name: gateway cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: - id: user-service # 路由标示,必须唯一 uri: lb://userservice # 路由的目标地址 predicates: # 路由断言,判断请求是否符合规则 - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合 - id: order-service uri: lb://orderservice predicates: - Path=/order/** filters: #过滤器,针对某一个具体服务 - AddRequestHeader=Truth,Itcast is freaking awesome!
如果想要对所有的路由都生效,可以使用default-filters进行配置,配置具体如下:
server: port: 10010 logging: level: cn.itcast: debug pattern: dateformat: MM-dd HH:mm:ss:SSS spring: application: name: gateway cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: - id: user-service # 路由标示,必须唯一 uri: lb://userservice # 路由的目标地址 predicates: # 路由断言,判断请求是否符合规则 - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合 - id: order-service uri: lb://orderservice predicates: - Path=/order/** default-filters: #默认过滤器,对所有路由都起作用 - AddRequestHeader=Truth,Itcast is freaking awesome!
五、全局过滤器GloableFilter
1.GateFilter和GloableFilter区别
GateFilter是基于配置文件的,处理逻辑是固定的。反之GloableFilter是基于Java代码实现的逻辑,实现方式是实现GloableFilter接口。
public interface GlobalFilter {
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
2.实现过滤器对用户身份进行校验
自定义类,实现GloableFilter接口:
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取请求参数
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
//2.获取authorization参数
String auth = queryParams.getFirst("authorization");
//3.校验
if("admin".equals(auth)){
//通过
return chain.filter(exchange);
}
//4.拦截
//4.1设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//4.2拦截请求
return exchange.getResponse().setComplete();
}
}
在上述代码中,@order注解是过滤器的执行的优先级,值越小优先级越高,我们除了使用@order注解外还可以让类实现Orderd接口:
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取请求参数
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
//2.获取authorization参数
String auth = queryParams.getFirst("authorization");
//3.校验
if("admin".equals(auth)){
//通过
return chain.filter(exchange);
}
//4.拦截
//4.1设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//4.2拦截请求
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return 0;
}
}
3.过滤器的执行顺序:
请求进入网关会碰到三类过滤器:当前路由的过滤器、 DefaultFilter 、 GlobalFilter
请求路由后,会将当前路由过滤器和 DefaultFilter 、 GlobalFilter ,合并到一个过滤器链(集合)中,排序后依次执行每个过滤器。
执行顺序如下:
每一个过滤器都必须指定一个 int 类型的 order 值, order 值越小,优先级越高,执行顺序越靠前。
GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值,由我们自己指定
路由过滤器和 defaultFilter 的 order 由 Spring 指定,默认是按照声明顺序从 1 递增。
当过滤器的order值一样时,会按照 defaultFilter> 路由过滤器>GlobalFilter的顺序执行
4.小结
全局过滤器作用:对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器步骤:自定义类实现GloableFilter接口、添加@Order注解或者实现Orderd接口、编写业务逻辑处理。
过滤器执行顺序:(1)Order值越小,优先级越高
(2)Order相同时,按照 defaultFilter> 路由过滤器>GlobalFilter的顺序执行
六、跨域处理
网关处理跨域采用的同样是 CORS 方案,并且只需要简单配置即可实现:
spring:
cloud:
gateway:
# 。。。
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期