日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
SpringCloud實戰(zhàn)小貼士:Zuul處理Cookie和重定向

由于我們在之前所有的入門教程中,對于HTTP請求都采用了簡單的接口實現(xiàn)。而實際使用過程中,我們的HTTP請求要復(fù)雜的多,比如當(dāng)我們將Spring Cloud Zuul作為API網(wǎng)關(guān)接入網(wǎng)站類應(yīng)用時,往往都會碰到下面這兩個非常常見的問題:

公司主營業(yè)務(wù):成都做網(wǎng)站、網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出新民免費做網(wǎng)站回饋大家。

  • 會話無法保持
  • 重定向后的HOST錯誤

本文將幫助大家分析問題原因并給出解決這兩個常見問題的方法。

一、會話保持問題

通過跟蹤一個HTTP請求經(jīng)過Zuul到具體服務(wù),再到返回結(jié)果的全過程。我們很容易就能發(fā)現(xiàn),在傳遞的過程中,HTTP請求頭信息中的Cookie和Authorization都沒有被正確地傳遞給具體服務(wù),所以最終導(dǎo)致會話狀態(tài)沒有得到保持的現(xiàn)象。

那么這些信息是在哪里丟失的呢?我們從Zuul進行路由轉(zhuǎn)發(fā)的過濾器作為起點,來一探究竟。下面是RibbonRoutingFilter過濾器的實現(xiàn)片段:

 
 
 
 
  1. public class RibbonRoutingFilter extends ZuulFilter{
  2.     ...
  3.     protected ProxyRequestHelper helper;
  4.     
  5.     @Override
  6.     public Object run() {
  7.         RequestContext context = RequestContext.getCurrentContext();
  8.         this.helper.addIgnoredHeaders();
  9.         try {
  10.             RibbonCommandContext commandContext = buildCommandContext(context);
  11.             ClientHttpResponse response = forward(commandContext);
  12.             setResponse(response);
  13.             return response;
  14.         }
  15.         ...
  16.         return null;
  17.     }
  18.     
  19.         protected RibbonCommandContext buildCommandContext(RequestContext context) {
  20.         HttpServletRequest request = context.getRequest();
  21.         MultiValueMap headers = this.helper
  22.                 .buildZuulRequestHeaders(request);
  23.         MultiValueMap params = this.helper
  24.                 .buildZuulRequestQueryParams(request);
  25.         ...
  26.     }
  27. }

這里有三個重要元素:

  • 過濾器的核心邏輯run函數(shù)實現(xiàn),其中調(diào)用了內(nèi)部函數(shù)buildCommandContext來構(gòu)建上下文內(nèi)容
  • 而buildCommandContext中調(diào)用了helper對象的buildZuulRequestHeaders方法來處理請求頭信息
  • helper對象是ProxyRequestHelper類的實例

接下來我們再看看ProxyRequestHelper的實現(xiàn):

 
 
 
 
  1. public class ProxyRequestHelper {
  2.     public MultiValueMap buildZuulRequestHeaders(
  3.             HttpServletRequest request) {
  4.         RequestContext context = RequestContext.getCurrentContext();
  5.         MultiValueMap headers = new HttpHeaders();
  6.         Enumeration headerNames = request.getHeaderNames();
  7.         if (headerNames != null) {
  8.             while (headerNames.hasMoreElements()) {
  9.                 String name = headerNames.nextElement();
  10.                 if (isIncludedHeader(name)) {
  11.                     Enumeration values = request.getHeaders(name);
  12.                     while (values.hasMoreElements()) {
  13.                         String value = values.nextElement();
  14.                         headers.add(name, value);
  15.                     }
  16.                 }
  17.             }
  18.         }
  19.         Map zuulRequestHeaders = context.getZuulRequestHeaders();
  20.         for (String header : zuulRequestHeaders.keySet()) {
  21.             headers.set(header, zuulRequestHeaders.get(header));
  22.         }
  23.         headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
  24.         return headers;
  25.     }
  26.     public boolean isIncludedHeader(String headerName) {
  27.         String name = headerName.toLowerCase();
  28.         RequestContext ctx = RequestContext.getCurrentContext();
  29.         if (ctx.containsKey(IGNORED_HEADERS)) {
  30.             Object object = ctx.get(IGNORED_HEADERS);
  31.             if (object instanceof Collection && ((Collection) object).contains(name)) {
  32.                 return false;
  33.             }
  34.         }
  35.         ...
  36.     }
  37. }

從上述源碼中,我們可以看到構(gòu)建頭信息的方法buildZuulRequestHeaders通過isIncludedHeader函數(shù)來判斷當(dāng)前請求的各個頭信息是否在忽略的頭信息清單中,如果是的話就不組織到此次轉(zhuǎn)發(fā)的請求中去。那么這些需要忽略的頭信息是在哪里初始化的呢?在PRE階段的PreDecorationFilter過濾器中,我們可以找到答案:

 
 
 
 
  1. public class PreDecorationFilter extends ZuulFilter{
  2.     ...
  3.     public Object run() {
  4.         RequestContext ctx = RequestContext.getCurrentContext();
  5.         final String requestURI = this.urlPathHelper.getPathWithinApplication(ctx.getRequest());
  6.         Route route = this.routeLocator.getMatchingRoute(requestURI);
  7.         if (route != null) {
  8.             String location = route.getLocation();
  9.             if (location != null) {
  10.                 ctx.put("requestURI", route.getPath());
  11.                 ctx.put("proxy", route.getId());
  12.                 // 處理忽略頭信息的部分
  13.                 if (!route.isCustomSensitiveHeaders()) {
  14.                     this.proxyRequestHelper.addIgnoredHeaders(
  15.                         this.properties.getSensitiveHeaders()
  16.                         .toArray(new String[0]));
  17.                 } else {
  18.                     this.proxyRequestHelper.addIgnoredHeaders(
  19.                         route.getSensitiveHeaders()
  20.                         .toArray(new String[0]));
  21.                 }
  22.         ...
  23. }

從上述源碼中,我們可以看到有一段if/else塊,通過調(diào)用ProxyRequestHelper的addIgnoredHeaders方法來添加需要忽略的信息到請求上下文中,供后續(xù)ROUTE階段的過濾器使用。這里的if/else塊分別用來處理全局設(shè)置的敏感頭信息和指定路由設(shè)置的敏感頭信息。而全局的敏感頭信息定義于ZuulProperties中:

 
 
 
 
  1. @Data
  2. @ConfigurationProperties("zuul")
  3. public class ZuulProperties{
  4.     private Set sensitiveHeaders = new LinkedHashSet<>(
  5.             Arrays.asList("Cookie", "Set-Cookie", "Authorization"));
  6.     ...
  7. }

所以解決該問題的思路也很簡單,我們只需要通過設(shè)置sensitiveHeaders即可,設(shè)置方法分為兩種:

1. 全局設(shè)置:

  • zuul.sensitive-headers=

2. 指定路由設(shè)置:

  • zuul.routes. .sensitive-headers=
  • zuul.routes. .custom-sensitive-headers=true

二、重定向問題

在使用Spring Cloud Zuul對接Web網(wǎng)站的時候,處理完了會話控制問題之后。往往我們還會碰到如下圖所示的問題,我們在瀏覽器中通過Zuul發(fā)起了登錄請求,該請求會被路由到某WebSite服務(wù),該服務(wù)在完成了登錄處理之后,會進行重定向到某個主頁或歡迎頁面。此時,仔細的開發(fā)者會發(fā)現(xiàn),在登錄完成之后,我們?yōu)g覽器中URL的HOST部分發(fā)生的改變,該地址變成了具體WebSite服務(wù)的地址了。這就是在這一節(jié),我們將分析和解決的重定向問題!

出現(xiàn)該問題的根源是Spring Cloud Zuul沒有正確的處理HTTP請求頭信息中的Host導(dǎo)致。在Brixton版本中,Spring Cloud Zuul的PreDecorationFilter過濾器實現(xiàn)時完全沒有考慮這一問題,它更多的定位于REST API的網(wǎng)關(guān)。所以如果要在Brixton版本中增加這一特性就相對較為復(fù)雜,不過好在Camden版本之后,Spring Cloud Netflix 1.2.x版本的Zuul增強了該功能,我們只需要通過配置屬性zuul.add-host-header=true就能讓原本有問題的重定向操作得到正確的處理。關(guān)于更多Host頭信息的處理,讀者可以參考本文之前的分析思路,可以通過查看PreDecorationFilter過濾器的源碼來詳細更多實現(xiàn)細節(jié)。

【本文為專欄作者“翟永超”的原創(chuàng)稿件,轉(zhuǎn)載請通過聯(lián)系作者獲取授權(quán)】


網(wǎng)站名稱:SpringCloud實戰(zhàn)小貼士:Zuul處理Cookie和重定向
本文鏈接:http://m.5511xx.com/article/coicscd.html