目录
1、概念图
2、路由
2.1 maven项目
2.2 login-server
2.2.1 接口
2.3 gateway
3、路由方式
3.1 配置文件路由
3.2 代码路由
4、动态路由
4.1 多个路径
4.2 负载均衡
4.2.1 eureka客户端
4.2.2 开启客户端
4.2.3 修改配置文件
4.2.4 访问
5、断言工程(predicates)
5.1 the After route predicate factory
6、过滤器
6.1 ip限制
6.2 token校验
不需要选择web,web里面的服务器是tomcat,Gateway里面的服务器是Netty。
Spring Cloud Gateway
Spring Cloud Gateway
注意:login-server也需要注册到eureka
http://localhost/应用名称/路径
Spring Cloud Gateway
断言是个某个路由设置的。
请求必须在指定的时间之后。
获取当前时间:ZonedDateTime.now()
2023-04-11T16:43:28.874+08:00[Asia/Shanghai]
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 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 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;
}
}
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 black_list = Arrays.asList("127.0.0.1");
@Override
public Mono 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 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;
}
}
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 ALLOW_URL = Arrays.asList("/login-server/doLogin");
@Override
public Mono 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 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 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));
}
}