1. 程式人生 > >SpringCloud(8)---zuul權限校驗、接口限流

SpringCloud(8)---zuul權限校驗、接口限流

limit 數字 講解 alt resp 過濾 ext.get sys 用戶信息

zuul權限校驗、接口限流

一、權限校驗搭建

正常項目開發時,權限校驗可以考慮JWT和springSecurity結合進行權限校驗,這個後期會總結,這裏做個基於ZuulFilter過濾器進行一個簡單的權限校驗過濾。

對於組件zuul中,其實帶有權限認證的功能,那就是ZuulFilter過濾器。ZuulFilter是Zuul中核心組件,通過繼承該抽象類,覆寫幾個關鍵方法達到自定義調度請求的作用

使用到的組件包括:Eureka、Feign、Zuul,包括以下四個項目:

(1)Eureka-server: 7001 註冊中心

(2)product-server : 8001 商品微服務

(3)order-server : 9001 訂單微服務

(4)zuul-gateway : 6001 Zuul網關

技術分享圖片

有關四個服務的基本配置我這裏就不寫了,具體可以看之前幾篇博客,這裏只寫LoginFilter權限校驗類

1、LoginFilter類

/**
 * 登錄過濾器
*記得類上加Component註解
*/ @Component public class LoginFilter extends ZuulFilter { /** * 過濾器類型,前置過濾器 */ @Override public String filterType()
{
return PRE_TYPE; } /** * 過濾器順序,越小越先執行 */ @Override public int filterOrder() { return 4; } /** * 過濾器是否生效 * 返回true代表需要權限校驗,false代表不需要用戶校驗即可訪問 */ @Override public boolean shouldFilter() { //共享RequestContext,上下文對象
RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletRequest request = requestContext.getRequest(); System.out.println(request.getRequestURI()); //需要權限校驗URL if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) { return true; } else if ("/apigateway/order/api/v1/order/list".equalsIgnoreCase(request.getRequestURI())) { return true; } else if ("/apigateway/order/api/v1/order/find".equalsIgnoreCase(request.getRequestURI())) { return true; } return false; } /** * 業務邏輯 * 只有上面返回true的時候,才會進入到該方法 */ @Override public Object run() throws ZuulException { //JWT RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletRequest request = requestContext.getRequest(); //token對象,有可能在請求頭傳遞過來,也有可能是通過參數傳過來,實際開發一般都是請求頭方式 String token = request.getHeader("token"); if (StringUtils.isBlank((token))) { token = request.getParameter("token"); } System.out.println("頁面傳來的token值為:" + token); //登錄校驗邏輯 如果token為null,則直接返回客戶端,而不進行下一步接口調用 if (StringUtils.isBlank(token)) { // 過濾該請求,不對其進行路由 requestContext.setSendZuulResponse(false); //返回錯誤代碼 requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); } return null; } }

2、關鍵說明

(1)方法說明

filterType : filter類型,分為pre、error、post、 route

filterOrder: filter執行順序,通過數字指定,數字越小,執行順序越先

shouldFilter: filter是否需要執行 true執行 false 不執行

run : filter具體邏輯(上面為true那麽這裏就是具體執行邏輯)

(2)filter類型說明

pre: 請求執行之前filter

route: 處理請求,進行路由

post: 請求處理完成後執行的filter

error: 出現錯誤時執行的filter

3、測試

先在請求頭和傳參都不傳token,校驗失敗:返回401狀態碼

技術分享圖片

在參數的時候傳入token

技術分享圖片

看後臺輸出
技術分享圖片

說明模擬校驗通過,返回用戶信息。

二、接口限流搭建

接口限流可以在nginx層面做限流,也可以在網關層面做限流,這裏在網關層面做限流,基於guava框架來做網關限流。

先對guava框架限流的概念進行講解下:

技術分享圖片

它的大致意思就是每一個請求進來先到桶裏去拿令牌,拿到令牌的請求放行,假設你設置了1000個令牌,如果拿完了,那麽後面來調接口的請求就需要排隊等有新的令牌才能調用該接口。

OrderRateLimiterFilter限流過濾類

/**
 * 訂單限流
 *其它和上面都一樣,只是run()中邏輯不一樣
 */
@Component
public class OrderRateLimiterFilter extends ZuulFilter {


    //每秒產生1000個令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return -4;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();

        //只對訂單接口限流
        if ("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())) {
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();

        //就相當於每調用一次tryAcquire()方法,令牌數量減1,當1000個用完後,那麽後面進來的用戶無法訪問上面接口
        //當然這裏只寫類上面一個接口,可以這麽寫,實際可以在這裏要加一層接口判斷。
        if (!RATE_LIMITER.tryAcquire()) {
            requestContext.setSendZuulResponse(false);
            //HttpStatus.TOO_MANY_REQUESTS.value()裏面有靜態代碼常量
            requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
        }
        return null;
    }
}


我只是偶爾安靜下來,對過去的種種思忖一番。那些曾經的舊時光裏即便有過天真愚鈍,也不值得譴責。畢竟,往後的日子,還很長。不斷鼓勵自己,

天一亮,又是嶄新的起點,又是未知的征程(上校10)

SpringCloud(8)---zuul權限校驗、接口限流