介绍
gateway是Spring Cloud家族中功能强大的网关服务,除了做请求路由之外,还有做到定制化的请求过滤、鉴权等功能,是Spring生态圈基于Java实现的;
做为网关,nginx能做的,它都能做,nginx做不到的,我们也可以通过gateway的过滤器也实现;
项目搭建
引入pom
<!-- spring-boot版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 网关相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- spring-cloud版本管理器,Greenwich.RELEASE版本 -->
<dependencyManagement>
<!--spring cloud依赖版本管理-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
配置yml文件
server:
port: 9092
spring:
application:
name: authing-gateway
cloud:
gateway:
routes:
- id: service-test
uri: https://gateway-test.xxxx.com
predicates:
- Path=/region/**
# 跨域配置
globalcors:
cors-configurations:
'[/**]':
allow-credentials: true
allowed-origins: "*"
allowed-headers: "*"
allowed-methods:
- OPTIONS
- GET
- POST
- PUT
- DELETE
过滤器
Gateway有两种过滤器,GateWayFilter路由过滤器,GlobalFilter全局过滤器;下面我们演示添加全局过滤器
import cn.authing.core.auth.AuthenticationClient;
import org.springframework.beans.factory.annotation.Autowired;
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.util.CollectionUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Map;
/**
* @Date 2022-04-15
* @author sxt
* @describe 检查token是否合法过滤器
*/
@Component
public class TokenCheckFilter implements GlobalFilter, Ordered {
@Autowired
private AuthenticationClient authenticationClient;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 从请求头中获取token
List<String> token = request.getHeaders().get("token");
// token为空,直接返回
if(CollectionUtils.isEmpty(token)){
return createError(HttpStatus.UNAUTHORIZED, "token non-existent!", response);
}
// 校验token
try {
Map<String, Object> execute = (Map<String, Object>)authenticationClient.introspectToken(token.get(0)).execute();
if(!(boolean) execute.get("active")){
return createError(HttpStatus.FORBIDDEN, "illegal request!", response);
}
} catch (Exception e) {
return createError(HttpStatus.FORBIDDEN, "illegal request!", response);
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
/**
* 构建错误返回
* @param status
* @param msg msg仅支持英文
* @return
*/
private Mono<Void> createError(HttpStatus status, String msg, ServerHttpResponse response){
response.setStatusCode(status);
DataBuffer wrap = response.bufferFactory().wrap(msg.getBytes());
return response.writeWith(Mono.just(wrap));
}
}