微服务网关
GatewayFilter:路由过滤器,作用于任意指定的路由;默认不生效,要配置到路由后生效。GlobalFilter:全局过滤器,作用范围是所有路由;声明后自动生效。示例:GlobalFilter@Component@Override//放行//代表优先级,值越小优先级越高@Overridereturn 0;
·
微服务网关
一、概念
网关就是网络的接口,负责请求的路由、转发、身份校验。
二、快速入门
1.创建依赖
2.引入网关依赖
<!--网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
3.编写启动类
4.配置路由规则
server:
port: 8080
spring:
application:
name: gateway
cloud:
nacos:
server-addr: 192.168.86.128:8848
gateway:
routes:
- id: item
uri: lb://item-service
predicates:
- Path=/items/**,/search/**
三、路由过滤器
这是全局过滤器,局部过滤器是配置在routes里面,即predicates下面(不加default)
default-filters:
- AddRequestHeader=truth,patience is key in life

四、网关登录校验


1.如何在网关登录校验之前做登录校验?
- 首先自定义一个过滤器,保证这个过滤器的执行顺序在nettyRoutingFilter之前
- 然后在他的pre逻辑里去实现jwt校验
2.网关如何将用户信息传递给微服务?
- 网关在校验完后将用户放到请求头,然后再发请求到微服务,微服务再从请求头里取出用户
接下来需要做的事情:
- 如何在网关里去自定义过滤器,并控制顺序?
- 如何在网关里编写登录校验的逻辑?
- 这样把网关里得到的用户向下游微服务传递?
- 微服务之间怎么区传递?
1.自定义过滤器
过滤器有两种:
- GatewayFilter:路由过滤器,作用于任意指定的路由;默认不生效,要配置到路由后生效。
- GlobalFilter:全局过滤器,作用范围是所有路由;声明后自动生效。
示例:GlobalFilter
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
HttpHeaders headers = request.getHeaders();
System.out.println("headers: " + headers);
//放行
return chain.filter(exchange);
}
//代表优先级,值越小优先级越高
@Override
public int getOrder() {
return 0;
}
}
2.实现登录校验
需求:在网关中基于过滤器实现登录校验功能。
该功能在hm-getway模块。
@Component
@RequiredArgsConstructor
public class AuthGlobalFilter implements GlobalFilter, Ordered {
private final AuthProperties authProperties;
private final JwtTool jwtTool;
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取Request
ServerHttpRequest request = exchange.getRequest();
//判断是否需要拦截器拦截
if(isExclude(request.getPath().toString())){
return chain.filter(exchange);
}
//获取token
String token=null;
List<String> heards = request.getHeaders().get("authorization");
if(heards!=null && !heards.isEmpty()){
token = heards.get(0);
}
//校验并解析token
Long userId = null;
try {
userId = jwtTool.parseToken(token);
} catch (Exception e) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
System.out.println("用户id:"+userId);
//放行
return chain.filter(swe);
}
private boolean isExclude(String path) {
List<String> excludePaths = authProperties.getExcludePaths();
for (String ePath : excludePaths) {
if(antPathMatcher.match(ePath, path)){
return true;
}
}
return false;
}
@Override
public int getOrder() {
return 0;
}
}
3. 网关传递用户
首先,在getway的AuthGlobalFilter添加相关信息(即将上方System.out.println(“用户id:”+userId);改成下方代码)
//TODO 传递用户信息
String userInfo=userId.toString();
ServerWebExchange swe = exchange.mutate()
.request(builder -> builder.header("user-info", userInfo))
.build();
然后,在hm-common添加拦截器
public class UserInfoInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取登录用户信息
String header = request.getHeader("user-info");
//判断是否获取了用户,如果有,存入ThreadLocal
if (StrUtil.isNotBlank(header)) {
UserContext.setUser(Long.valueOf(header));
}
//放行
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserContext.removeUser();
}
}
最后,定义springmvc的配置类定义拦截器
@Configuration
// 判断DispatcherServlet类是否存在(是否是微服务,只要是微服务都有spirngmvc,有springmvc就有其核心api,即下方注解的类)
@ConditionalOnClass(DispatcherServlet.class)
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserInfoInterceptor());
}
}
配置完后还有问题:每个微服务启动类所在的包都不一样,导致每个微服务的包都扫不到common里的mvcconfig,使得配置类不生效。
方案:在resources包的META-INF包下定义一个文件去记录这些配置类,这样项目一启动就会找到这些配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.hmall.common.config.MvcConfig
4.OpenFeign传递用户

定义oprnFeign的拦截器,保存用户到请求头
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
public RequestInterceptor userInfoRequestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
Long userId = UserContext.getUser();
if (userId != null) {
requestTemplate.header("user-info",userId.toString());
}
}
};
}
@Bean
public ItemClientFallbackFactory itemClientFallbackFactory() {
return new ItemClientFallbackFactory();
}
}

更多推荐


所有评论(0)