目录
5.1 the After route predicate factory
1、概念图
2、路由
2.1 maven项目
2.2 login-server
2.2.1 接口
2.3 gateway
不需要选择web,web里面的服务器是tomcat,Gateway里面的服务器是Netty。
3、路由方式
3.1 配置文件路由
3.2 代码路由
4、动态路由
4.1 多个路径
4.2 负载均衡
4.2.1 eureka客户端
4.2.2 开启客户端
4.2.3 修改配置文件
注意:login-server也需要注册到eureka
4.2.4 访问
5、断言工程(predicates)
断言是个某个路由设置的。
5.1 the After route predicate factory
请求必须在指定的时间之后。
获取当前时间:ZonedDateTime.now()
2023-04-11T16:43:28.874+08:00[Asia/Shanghai]
6、过滤器
gateway里面的过滤器和Servlet里面的过滤器,功能差不多,路由过滤器可以用于修改进入Http请求和返回Http响应。
GlobalFilter全局过滤器,不需要配置路由,系统初始化作用到所有路由上。
全局过滤器统计请求次数限流token的校验﹐ip黑名单拦截跨域本质(filter)。
144开头的电话限制一些ip的访问。
Order的包:org.springframework.core.Ordered
package com.powernode.gatewayserver.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.lang.annotation.Annotation;
import java.util.HashMap;
/**
* 全局过滤
*/
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
/**
* 过滤的方法
* 责任链设计模式
* chain.filter(exchange) 放行
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//针对请求的过滤 ServerHttpRequest是WebFlux响应式的
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
System.out.println(path);
HttpHeaders headers = request.getHeaders();
System.out.println(headers);
String methodName = request.getMethod().name();
System.out.println(methodName);
String ip = headers.getHost().getHostString();
System.out.println(ip);
//拦截 响应相关的数据
ServerHttpResponse response = exchange.getResponse();
//微服务,前后端分离,通过json来交付
//{"code":200,"msg":"ok"}
//设置编码 响应头设置
response.getHeaders().set("content-type","application/json;charset=utf-8");
//组装业务返回值
HashMap<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.UNAUTHORIZED.value());
map.put("msg","你未授权");
ObjectMapper objectMapper = new ObjectMapper();
//把map转换成字节 返回的是Mono类型
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//通过buffer工厂将字节数组包装成数据包
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
//return chain.filter(exchange);
}
/**
* 指定顺序的方法
* 越小越执行
*/
@Override
public int getOrder() {
return 0;
}
}
6.1 ip限制
ip黑名单和白名单。
package com.powernode.gatewayserver.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
* 网关拦截
* 业务服务 黑名单
* 数据库服务 白名单
*/
@Component
public class IpCheckFilter implements GlobalFilter , Ordered {
/**
* 拿到ip
* 校验ip
* 放行或者拦截
*/
public static final List<String> black_list = Arrays.asList("127.0.0.1");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String ip = request.getHeaders().getHost().getHostString();
//查询数据库
if (!black_list.contains(ip)) {
//放行
return chain.filter(exchange);
}
//拦截
ServerHttpResponse response = exchange.getResponse();
//设置响应的编码
response.getHeaders().set("content-type","application/json;charset=utf-8");
HashMap<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.UNAUTHORIZED.value());
map.put("msg","拦截"+ip);
//map转化成字节数组
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//通过buffer工厂打包成数据包
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
}
@Override
public int getOrder() {
return 1;
}
}
6.2 token校验
package com.powernode.gatewayserver.filter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class TokenCheckFilter implements GlobalFilter {
/**
* 一般放在请求头里面 Authorization
* 1、拿到请求url
* 2、判断方向
* 3、拿到请求头
* 4、拿到token
* 5、校验
* 6、放行/拦截
*/
public static final List<String> ALLOW_URL = Arrays.asList("/login-server/doLogin");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
RequestPath path = request.getPath();
if (ALLOW_URL.contains(path)){
return chain.filter(exchange);
}
//检查
HttpHeaders headers = request.getHeaders();
List<String> authorization = headers.get("Authorization");
if (!CollectionUtils.isEmpty(authorization)){
String token = authorization.get(0);
if (StringUtils.hasText(token)){
//约定好前缀 bearer
String realToken = token.replaceFirst("bearer", "");
if (StringUtils.hasText(realToken)){
return chain.filter(exchange);
}
}
}
//拦截 响应相关的数据
ServerHttpResponse response = exchange.getResponse();
//微服务,前后端分离,通过json来交付
//{"code":200,"msg":"ok"}
//设置编码 响应头设置
response.getHeaders().set("content-type","application/json;charset=utf-8");
//组装业务返回值
HashMap<String, Object> map = new HashMap<>();
map.put("code", HttpStatus.UNAUTHORIZED.value());
map.put("msg","你未授权");
ObjectMapper objectMapper = new ObjectMapper();
//把map转换成字节 返回的是Mono类型
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//通过buffer工厂将字节数组包装成数据包
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
}
}