天天看点

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter

SpringCloud Api Gateway+Consul 动态路由+过滤器Filter

      • 1.工程pom.xml 引入 依赖
      • 2.添加启动类
      • 3.配置yml文件
        • 1.配置ApiGateway进consul注册中心
        • 2.配置ApiGateway进consul注册中心
      • 4.分别启动consul、service、apigateway
        • 1.每个服务都启动好
        • 2.输入地址查看运行结果:http://localhost:8500/ui/dc1/services
      • 5.测试
        • 1.访问gateway地址
      • 6.过滤器Filter
        • 1.创建AuthorizeFilter类

1.工程pom.xml 引入 依赖

<!-- spring cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
           

注意web的依赖要移除掉,不然会报错。

2.添加启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableDiscoveryClient
@ComponentScan(basePackages= {"com.company.*"})
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}
           

在启动类中增加 注解 @EnableDiscoveryClient

3.配置yml文件

1.配置ApiGateway进consul注册中心

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter
spring:
  application:
    name: apigateway
  consul:
    host: localhost
    port: 8500
           

2.配置ApiGateway进consul注册中心

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter
cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
          lower-case-service-id: true
      routes:
      - id: service #路由的ID
        #uri: http://localhost:8082
        uri: lb://application #匹配后提共服务的路由地址
        predicates:
          - Path=/service/**
        filters:
        - StripPrefix=1
        # 熔断降级配置
        - name: Hystrix
          args:
            name: default
            fallbackUri: forward:/fallback
           

4.分别启动consul、service、apigateway

1.每个服务都启动好

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter

2.输入地址查看运行结果:http://localhost:8500/ui/dc1/services

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter

一定要将服务与网关注册到consul里面去

5.测试

1.访问gateway地址

SpringCloud Gateway Consul注册中心配置动态路由+过滤器Filter

访问成功

6.过滤器Filter

1.创建AuthorizeFilter类

package com.company.author;

import cn.hutool.core.collection.CollUtil;
import com.company.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


import java.util.ArrayList;
import java.util.List;

/**
 * 过滤器
 */
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {
    //放行的路径
    private static List<String> whiteList = new ArrayList<>();
    static {
        whiteList.add("/service/login/login");
        whiteList.add("/service/school/getSchoolList");
        whiteList.add("/service/school/getSchoolSectionSubjectList");
        whiteList.add("/service/register/checkPhone");
        whiteList.add("/service/register/getVerifyCode");
        whiteList.add("/service/register/register");
        whiteList.add("/service/swagger-resources/**");
        whiteList.add("/service/webjars/**");
        whiteList.add("/service/v2/**");
        whiteList.add("/service/doc.html/**");
        whiteList.add("/service/knowledge/getAllCfgSection");
    }
    //过滤
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    log.info("***************come in AuthorizeFilter*************************");
        ServerHttpRequest httpRequest = exchange.getRequest();
        //获取url
        String url = httpRequest.getURI().getPath();
        //判断url是否直接放行
        if (whiteList.contains(url)) {
            return chain.filter(exchange);
        }
        //通过token判断用户是否登录
        String token =null;
        if(CollUtil.isNotEmpty(exchange.getRequest().getQueryParams())){
            token = exchange.getRequest().getQueryParams().get("token").get(0);
        }
        String token1 = httpRequest.getHeaders().getFirst("token");
        // 缓存存在
        if (StringUtils.isEmpty(token) && StringUtils.isEmpty(token1)) {
            ServerHttpResponse serverHttpResponse = exchange.getResponse();
            String rsp = "{\"code\":\"2\",\"message\":\"用户未登陆\"}";
            DataBuffer d = serverHttpResponse.bufferFactory().wrap(rsp.getBytes());
            //指定编码
            serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return serverHttpResponse.writeWith(Flux.just(d));
        }
        //校验token是否过期
        Object userObj = RedisUtil.get(token);
        Object userObj1 = RedisUtil.get(token1);
        if (userObj == null && userObj1 == null) {
            ServerHttpResponse serverHttpResponse = exchange.getResponse();
            String rsp = "{\"code\":\"2\",\"message\":\"token已失效\"}";
            DataBuffer d = serverHttpResponse.bufferFactory().wrap(rsp.getBytes());
            //指定编码
            serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return serverHttpResponse.writeWith(Flux.just(d));
        }
        return chain.filter(exchange);
    }
    //按级别进行
    @Override
    public int getOrder() {
        return 0;
    }

}