小編給大家分享一下SpringCloud Zuul過濾器返回值攔截的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的三山網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!Zuul作為網(wǎng)關(guān)服務(wù),是其他各服務(wù)對外中轉(zhuǎn)站,通過Zuul進(jìn)行請求轉(zhuǎn)發(fā)。這就涉及到部分?jǐn)?shù)據(jù)是不能原封返回的,比如服務(wù)之間通信的憑證,用戶的加密信息等等。
舉個(gè)例子,用戶服務(wù)提供一個(gè)登錄接口,用戶名密碼正確后返回一個(gè)Token,此Token作為用戶服務(wù)的通行證,那么用戶登錄成功后返回的Token就需要進(jìn)行加密或者防止篡改處理。在到達(dá)用戶服務(wù)其他接口前,就需要對Token進(jìn)行校驗(yàn),非法的Token就不需要轉(zhuǎn)發(fā)到用戶服務(wù)中了,直接在網(wǎng)關(guān)層返回信息即可。
要修改服務(wù)返回的信息,需要使用的是Zuul的過濾器。使用時(shí)只需要繼承ZuulFilter,實(shí)現(xiàn)必要的方法即可。
Zuul提供默認(rèn)的四種過濾器類型,通過filterType方法進(jìn)行標(biāo)識(shí)
pre:可以在請求被路由之前調(diào)用
route:在路由請求時(shí)候被調(diào)用
post:在route和error過濾器之后被調(diào)用
error:處理請求時(shí)發(fā)生錯(cuò)誤時(shí)被調(diào)用
過濾器執(zhí)行的順序是通過filterOrder方法進(jìn)行排序,越小的值越優(yōu)先處理。FilterConstants定義了一些列默認(rèn)的過濾器的執(zhí)行順序和路由類型,大部分需要用到的常量都在這兒。
例子中說明的,只有登錄接口需要攔截,所以只需要攔截登錄請求(/user/login)即可??梢酝ㄟ^過濾器的shouldFilter方法進(jìn)行判斷是否需要攔截。
由于是在準(zhǔn)發(fā)用戶服務(wù)成功后進(jìn)行的數(shù)據(jù)修改,所以攔截器的類型時(shí)post類型的。整個(gè)類的實(shí)現(xiàn)如下:
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; } }
配置文件,中添加授權(quán)url和返回token的key:
system.config.authFilter.authUrl=/user/login
system.config.authFilter.tokenKey=token
context.setResponseBody(body);這段代碼是核心,通過此方法修改返回?cái)?shù)據(jù)。
當(dāng)用戶登錄成功后,根據(jù)返回的token,通過授權(quán)服務(wù)進(jìn)行token加密,這里加密方式使用的是JWT。防止用戶篡改信息,非法的請求直接可以攔截在網(wǎng)關(guān)層。
關(guān)于Zuul過濾器的執(zhí)行過程,這里不需要多說明,源碼一看便知,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(); } }
方法說明:
preRoute:執(zhí)行pre類型的過濾器
postRoute:執(zhí)行post類型的過濾器
route:執(zhí)行route類型的過濾器
error:執(zhí)行error類型的過濾器
通過context.setSendZuulResponse(false)可以終止請求的轉(zhuǎn)發(fā),但是只在pre類型的過濾器中設(shè)置才可以。
關(guān)于如何終止過濾器:
只有pre類型的過濾器支持終止轉(zhuǎn)發(fā),其他過濾器都是按照順序執(zhí)行的,而且pre類型的過濾器也只有在所有pre過濾器執(zhí)行完后才可以終止轉(zhuǎn)發(fā),做不到終止過濾器繼續(xù)執(zhí)行??碯uulServletFilter源碼代碼:
// 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過濾器返回值攔截的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)頁題目:SpringCloudZuul過濾器返回值攔截的示例分析-創(chuàng)新互聯(lián)
瀏覽路徑:http://www.rwnh.cn/article48/cspehp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、定制網(wǎng)站、微信小程序、小程序開發(fā)、響應(yīng)式網(wǎng)站、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容