三大核心概念
Route(路由)
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
Predicate(断言)
参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter(过滤)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
使用
一、 maven配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
二、 yml配置
spring:
application:
name: cloud-gateway
cloud:
gateway:
httpclient:
connect-timeout: 5000
response-timeout: 5s
routes:
- id: devutil-api-project
uri: lb://devutil-api-project
predicates:
- Path=/api/project/**
- id: devutil-api-auth
uri: lb://devutil-api-auth
predicates:
- Path=/api/auth/**
三、Predicate的使用
下面列举一些常用的
1.After Route Predicate(在该时间之后)
- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
2.Header Route Predicate
- Header=Token, \d+
四、 Filter
-
CrossFilter.java
@Component public class CrossFilter implements GlobalFilter, Ordered { @Override public int getOrder() { return 0; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); HttpHeaders requestHeaders = request.getHeaders(); HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod(); ServerHttpResponse response = exchange.getResponse(); HttpHeaders headers = response.getHeaders(); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Token, Environment, Origin, X-Requested-With, Content-Type, Accept, Set-cookie"); headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "Token, Environment"); headers.add(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8"); if (requestMethod != null) { headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name()); } if (request.getMethod() == HttpMethod.OPTIONS) { response.setStatusCode(HttpStatus.OK); return Mono.empty(); } return chain.filter(exchange); } }
-
TokenFilter.java
@Component public class TokenFilter implements GlobalFilter, Ordered { @Autowired PathService pathService; @Autowired FeignAuthService authService; @Autowired PermService permService; @Override public int getOrder() { return 1; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); HttpHeaders headers = request.getHeaders(); MultiValueMap<String, String> params = request.getQueryParams(); String path = request.getPath().toString(); if (pathService.needToken(path)) { String token = headers.getFirst("Token"); //token不为空 if (!StringUtils.isBlank(token)) { Info authInfo = authService.validate(token); //校验token if (authInfo.getCode() == 0) { //token校验成功 String userId = ((Map) (authInfo.getData())).get("_uid_").toString(); if (permService.judgePerm(path, userId, params)) { //权限校验成功 return addUidParamFilter(exchange, chain, userId); } else { //无权限操作 Info resInfo = InfoUtil.getInfo(CommonError.PERM_LIMIT); return output(response, ParseUtil.toJson(resInfo)); } } } //token为空或校验失败 Info resInfo = InfoUtil.getInfo(CommonError.TOKEN_ERROR); return output(response, ParseUtil.toJson(resInfo)); } return chain.filter(exchange); } public Mono<Void> addUidParamFilter(ServerWebExchange exchange, GatewayFilterChain chain, String userId) { URI uri = exchange.getRequest().getURI(); StringBuilder query = new StringBuilder(); String originalQuery = uri.getRawQuery(); if (!StringUtils.isBlank(originalQuery)) { query.append(originalQuery); if (originalQuery.charAt(originalQuery.length() - 1) != '&') { query.append('&'); } } query.append("_uid_"); query.append('='); query.append(userId); try { URI newUri = UriComponentsBuilder.fromUri(uri) .replaceQuery(query.toString()) .build(true) .toUri(); ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build(); return chain.filter(exchange.mutate().request(request).build()); } catch (RuntimeException ex) { throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\""); } } public Mono<Void> output(ServerHttpResponse response, String message) { response.setStatusCode(HttpStatus.OK); byte[] bits = message.getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(bits); return response.writeWith(Mono.just(buffer)); } }
添加字段
public Mono<Void> addUidParamFilter(ServerWebExchange exchange, GatewayFilterChain chain, String userId) {
URI uri = exchange.getRequest().getURI();
StringBuilder query = new StringBuilder();
String originalQuery = uri.getRawQuery();
if (!StringUtils.isBlank(originalQuery)) {
query.append(originalQuery);
if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
query.append('&');
}
}
query.append("_uid_");
query.append('=');
query.append(userId);
try {
URI newUri = UriComponentsBuilder.fromUri(uri)
.replaceQuery(query.toString())
.build(true)
.toUri();
ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
return chain.filter(exchange.mutate().request(request).build());
} catch (RuntimeException ex) {
throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\"");
}
}
添加header
// 设置userId到request里,后续根据userId,获取用户信息
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("userId", 6)
.header("userName","李立").build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
return chain.filter(mutableExchange);
Comments | 0 条评论