国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

詳解SpringCloud Zuul過濾器返回值攔截

2024-07-14 08:41:14
字體:
來源:轉載
供稿:網友

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;   }

本文中的代碼已提交至: https://gitee.com/cmlbeliever/springcloud 歡迎Star 

實現類在:api-getway工程下的com.cml.springcloud.api.filter.AuthResponseFilter

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 星子县| 霍林郭勒市| 文山县| 兴仁县| 嘉善县| 射洪县| 浮梁县| 尉氏县| 大名县| 手游| 江源县| 西平县| 伊春市| 阜宁县| 霍林郭勒市| 邵武市| 阜阳市| 娄烦县| 玉门市| 交口县| 青神县| 久治县| 义马市| 定西市| 大兴区| 建昌县| 六枝特区| 东乌珠穆沁旗| 温宿县| 蒙自县| 武陟县| 齐齐哈尔市| 绵竹市| 隆回县| 嘉定区| 钦州市| 改则县| 霍林郭勒市| 临清市| 玉门市| 思茅市|