中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringCloud Zuul過濾器返回值攔截的示例分析

發布時間:2021-08-25 15:38:23 來源:億速云 閱讀:486 作者:小新 欄目:編程語言

小編給大家分享一下SpringCloud Zuul過濾器返回值攔截的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Zuul作為網關服務,是其他各服務對外中轉站,通過Zuul進行請求轉發。這就涉及到部分數據是不能原封返回的,比如服務之間通信的憑證,用戶的加密信息等等。

舉個例子,用戶服務提供一個登錄接口,用戶名密碼正確后返回一個Token,此Token作為用戶服務的通行證,那么用戶登錄成功后返回的Token就需要進行加密或者防止篡改處理。在到達用戶服務其他接口前,就需要對Token進行校驗,非法的Token就不需要轉發到用戶服務中了,直接在網關層返回信息即可。

要修改服務返回的信息,需要使用的是Zuul的過濾器。使用時只需要繼承ZuulFilter,實現必要的方法即可。

Zuul提供默認的四種過濾器類型,通過filterType方法進行標識

  1. pre:可以在請求被路由之前調用

  2. route:在路由請求時候被調用

  3. post:在route和error過濾器之后被調用

  4. error:處理請求時發生錯誤時被調用

過濾器執行的順序是通過filterOrder方法進行排序,越小的值越優先處理。FilterConstants定義了一些列默認的過濾器的執行順序和路由類型,大部分需要用到的常量都在這兒。

例子中說明的,只有登錄接口需要攔截,所以只需要攔截登錄請求(/user/login)即可。可以通過過濾器的shouldFilter方法進行判斷是否需要攔截。

由于是在準發用戶服務成功后進行的數據修改,所以攔截器的類型時post類型的。整個類的實現如下:

public class AuthResponseFilter extends AbstractZuulFilter {

 private static final String RESPONSE_KEY_TOKEN = "token";
 @Value("${system.config.authFilter.authUrl}")
 private String authUrl;
 @Value("${system.config.authFilter.tokenKey}")
 private String tokenKey = RESPONSE_KEY_TOKEN;

 @Autowired
 private AuthApi authApi;

 @Override
 public boolean shouldFilter() {
  RequestContext context = getCurrentContext();
  return StringUtils.equals(context.getRequest().getRequestURI().toString(), authUrl);
 }

 @Override
 public Object run() {

  try {
   RequestContext context = getCurrentContext();

   InputStream stream = context.getResponseDataStream();
   String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));

   if (StringUtils.isNotBlank(body)) {
    Gson gson = new Gson();
    @SuppressWarnings("unchecked")
    Map<String, String> result = gson.fromJson(body, Map.class);
    if (StringUtils.isNotBlank(result.get(tokenKey))) {
     AuthModel authResult = authApi.encodeToken(result.get(tokenKey));
     if (authResult.getStatus() != HttpServletResponse.SC_OK) {
      throw new IllegalArgumentException(authResult.getErrMsg());
     }
     String accessToken = authResult.getToken();
     result.put(tokenKey, accessToken);
    }
    body = gson.toJson(result);
   }
   context.setResponseBody(body);
  } catch (IOException e) {
   rethrowRuntimeException(e);
  }
  return null;
 }

 @Override
 public String filterType() {
  return FilterConstants.POST_TYPE;
 }

 @Override
 public int filterOrder() {
  return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 2;
 }

}

配置文件,中添加授權url和返回token的key:

system.config.authFilter.authUrl=/user/login
system.config.authFilter.tokenKey=token

context.setResponseBody(body);這段代碼是核心,通過此方法修改返回數據。

當用戶登錄成功后,根據返回的token,通過授權服務進行token加密,這里加密方式使用的是JWT。防止用戶篡改信息,非法的請求直接可以攔截在網關層。

關于Zuul過濾器的執行過程,這里不需要多說明,源碼一看便知,ZuulServletFilter:

@Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  try {
   init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
   try {
    preRouting();
   } catch (ZuulException e) {
    error(e);
    postRouting();
    return;
   }

   // Only forward onto to the chain if a zuul response is not being sent
   if (!RequestContext.getCurrentContext().sendZuulResponse()) {
    filterChain.doFilter(servletRequest, servletResponse);
    return;
   }

   try {
    routing();
   } catch (ZuulException e) {
    error(e);
    postRouting();
    return;
   }
   try {
    postRouting();
   } catch (ZuulException e) {
    error(e);
    return;
   }
  } catch (Throwable e) {
   error(new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_FROM_FILTER_" + e.getClass().getName()));
  } finally {
   RequestContext.getCurrentContext().unset();
  }
 }

方法說明:

  1. preRoute:執行pre類型的過濾器

  2. postRoute:執行post類型的過濾器

  3. route:執行route類型的過濾器

  4. error:執行error類型的過濾器

通過context.setSendZuulResponse(false)可以終止請求的轉發,但是只在pre類型的過濾器中設置才可以。

關于如何終止過濾器:

只有pre類型的過濾器支持終止轉發,其他過濾器都是按照順序執行的,而且pre類型的過濾器也只有在所有pre過濾器執行完后才可以終止轉發,做不到終止過濾器繼續執行。看ZuulServletFilter源碼代碼:

  // Only forward onto to the chain if a zuul response is not being sent
   if (!RequestContext.getCurrentContext().sendZuulResponse()) {
    filterChain.doFilter(servletRequest, servletResponse);
    return;
   }

以上是“SpringCloud Zuul過濾器返回值攔截的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

曲阜市| 正蓝旗| 金山区| 梁山县| 丹阳市| 固始县| 宁远县| 武邑县| 红原县| 尤溪县| 通海县| 颍上县| 洛南县| 林西县| 武夷山市| 昌吉市| 扶余县| 元阳县| 徐州市| 东源县| 元江| 阜城县| 嘉义市| 准格尔旗| 广昌县| 宁乡县| 巩义市| 齐齐哈尔市| 佳木斯市| 崇文区| 班玛县| 申扎县| 师宗县| 新安县| 阜城县| 广元市| 长葛市| 涞源县| 方城县| 临潭县| 张家港市|