SpringCloud 框架基本模塊梳理(三)

前言
本篇文章繼續上一篇gateway的鑑權使用說明。主要包含全局過濾器的設置和多路由跳轉,附帶做一下配置中心的講解。
一、全局過濾器
在gateway的官方文檔中,分兩種過濾器:全局過濾和路由過濾。本次採用全局過濾來輔助完成鑑權

@Component
public class Filter implements GlobalFilter {

    /*白名單暫時不做,只提一個登錄接口*/
    private final static String LOGIN_PATH = "/user/login";

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if(LOGIN_PATH.equals(exchange.getRequest().getPath().toString())) {
            exchange.getResponse().setStatusCode(HttpStatus.OK);
            return chain.filter(exchange);
        }
        /*暫時定義鑑權邏輯:有token就通過並刷新,沒有就直接不允許*/
        exchange.getResponse().setStatusCode(HttpStatus.FAILED_DEPENDENCY);
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        if(StringUtils.isNotEmpty(token)) {
            String str = redisTemplate.opsForValue().get(token);
            if(StringUtils.isNotEmpty(str)) {
                @SuppressWarnings("unchecked")
                Map<String,Object> map = (Map)JSONObject.parse(str);
                long timestamp = Long.parseLong(map.get("outTime").toString());
                LocalDateTime time =LocalDateTime.ofEpochSecond(timestamp/1000,0, ZoneOffset.ofHours(8));
                map.put("outTime",time.plusMinutes(10).toInstant(ZoneOffset.of("+8")).toEpochMilli());

                String jsonString = JSONObject.toJSONString(map);
                redisTemplate.opsForValue().set(token,jsonString);
                exchange.getResponse().setStatusCode(HttpStatus.OK);
            }
        }
        return chain.filter(exchange);
    }

}

這裏藉助了GlobalFilter來實現全局的一個請求過濾,主要複寫了filter,當中定義了我設想的token校驗邏輯;對於白名單暫時只是將登錄接口做免校驗。。。

二、路由轉發
在gateway的官方說明中,是提供兩種方式的路由轉發的。一是在配置文件中配置,如:

routes:
      # =====================================
      # to run server
      # $ wscat --listen 9000
      # to run client
      # $ wscat --connect ws://localhost:8080/echo
      - id: websocket_test
        uri: ws://localhost:9000
        order: 9000
        predicates:
        - Path=/echo
      # =====================================
      - id: default_path_to_httpbin
        uri: ${test.uri}
        order: 10000
        predicates:
        - Path=/**

另一種方式是api做路由轉發,如:

@Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route (r -> r.path ("/u/**")
                        .filters (f -> f.stripPrefix (1))
                        .uri ("lb://user")
                        .order (0)
                        .id ("user-route")
                )
                .route (r -> r.path ("/db/**")
                        .filters (f -> f.stripPrefix (1))
                        .uri ("lb://dbmanagement")
                        .order (0)
                        .id ("db-route")
                )
                .build();
    }

這裏簡單的闡述一下兩種方式的共同的參數意義
id:路由的唯一標識
uri:轉發的地址
order:序號(越大優先級越高)
filter:url斷言規則
(其實在配置文件中的路由轉發,本人並沒有實現,不知道是哪裏配出了問題,所以採用的是api的方式,望有大佬路過告知)

三、配置中心
關於springcloud config的配置和說明網上已經太多了,我這裏只是附帶提一下。
1、jar

<dependency>
 	<groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
</dependency>

2、啓動項註解

@EnableConfigServer

3、配置文件集中管理
目錄
類似如此的文件配置,丟在config服務下靜態資源處。

server:
  port: 19000

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: config
  profiles:
    active: native
  cloud:
    config:
      fail-fast: true
      server:
        native:
          search-locations: classpath:/config/

指定config讀取本地(profiles:active: native)

4、其他服務獲取配置文件

spring:
  cloud:
    config:
      profile: user
      discovery:
        enabled: true
        service-id: CONFIG
      fail-fast: true

指定配置中心服務的爲 CONFIG
文件名爲 user的配置文件

如此就可以在服務啓動時從配置中心拉取配置文件,eg:
啓動日誌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章