13.gateway中的過濾器的介紹以及自定義過濾器

cxrlover發表於2020-12-05

gateway中的過濾器的生命週期:

  • pre: 這種過濾器在請求被路由之前呼叫,可以利用這種過濾器完成身份認證、在叢集中選擇微服務完成客戶端負載均衡、記錄除錯資訊等
  • post: 這種過濾器在路由到微服務返回訊息後執行,這種過濾器可以為將響應從微服務傳送給客戶端,收集統計資訊和指標等

在這裡插入圖片描述

區域性過濾器

區域性過濾器只是針對單個路由的過濾器

在SpringCloud Gateway中內建了很多不同型別的閘道器路由過濾器。

內建過濾工廠推薦檢視這篇部落格:https://www.cnblogs.com/zhaoxiangjun/p/13042189.html

全域性過濾器

全域性過濾器作用於所有路由, 無需配置。通過全域性過濾器可以實現對許可權的統一校驗,安全性驗證等功能。

內建全域性過濾器

SpringCloud Gateway內部也是通過一系列的內建全域性過濾器對整個路由轉發進行處理如下:
在這裡插入圖片描述

自定以全域性過濾器

內建的過濾器已經可以完成大部分的功能,但是對於企業開發的一些業務功能處理,還是需要我們自己編寫過濾器來實現的,那麼我們一起通過程式碼的形式自定義一個過濾器,去完成統一的許可權校驗。

開發中的鑑權邏輯:

  • 客戶端第一次請求服務時,服務端對使用者進行資訊認證(登入)
  • 認證通過,將使用者資訊進行加密形成token,返回給客戶端,作為登入憑證
  • 以後每次請求,客戶端都攜帶認證的token
  • 服務端對token進行解密,判斷是否有效。

在這裡插入圖片描述
如上圖,對於驗證使用者是否已經登入鑑權的過程可以在閘道器統一檢驗。

檢驗的標準就是請求中是否攜帶token憑證以及token的正確性。

下面的我們自定義一個LoginGlobalFilter,去校驗所有請求的請求引數中是否包含“token”,如何不包含請求引數“token”則不轉發路由,否則執行正常的轉發邏輯

自定義全域性過濾器 要求:必須實現GlobalFilter,Order介面,使用@Component註解

程式碼:

@Component
public class LoginGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //獲取請求攜帶的token值。---->(1.可以在請求路徑上?  2.請求頭)
        //1. 可以在請求路徑上
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        // 獲取響應物件
        ServerHttpResponse response = exchange.getResponse();
        //2. 請求頭
        // String token = exchange.getRequest().getHeaders().getFirst("token");
        // 沒有token資料,表示還沒有登入,則讓使用者去登入,模擬返回 json 資料
        if(token==null){
            Map<String,Object>  map=new HashMap<>();
            map.put("code",100);
            map.put("message","請先登入");
            try {
                byte[] datas = JSON.toJSONString(map).getBytes("utf-8");
                DataBuffer buffer = response.bufferFactory().wrap(datas);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }catch (Exception e){}
        }
        // 這裡假設 token 的值是 ”admin“
        if(!StringUtils.equals(token,"admin")){
            Map<String,Object> map=new HashMap<>();
            map.put("code",101);
            map.put("message","登陸失效");
            try {
                byte[] datas = JSON.toJSONString(map).getBytes("utf-8");
                DataBuffer buffer = response.bufferFactory().wrap(datas);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }catch (Exception e){
            }
        }
        return chain.filter(exchange);//放行
    }

    // 優先順序值越小優先順序越高
    @Override
    public int getOrder() {
        return 0;
    }
}

配置完全域性過濾器之後,會自動生效,無需再配置

訪問後效果如下:

  • 正常登入:
    在這裡插入圖片描述

  • 未登入
    在這裡插入圖片描述

  • 登入失效:token值不對
    在這裡插入圖片描述

相關文章