Zuul作為網關的其中一個重要功能,就是實現請求的鑒權。而這個動作我們往往是通過Zuul提供的過濾器來實現的。
一、過濾器方法的作用
想要使用Zuul實現過濾功能,我們需要自定義一個類繼承ZuulFilter類,並實現其中的四個方法,我們先看一下這四個方法的作用是什么
public class MyFilter extends ZuulFilter {
/**
* filterType:返回字符串,代表過濾器的類型。包含以下4種:
* -- pre:請求在被路由之前執行
* -- route:在路由請求時調用
* -- post:在route和errror過濾器之后調用
* -- error:處理請求時發生錯誤調用
* @return 返回以上四個類型的名稱
*/
@Override
public String filterType() {
return null;
}
/**
* filterOrder:通過返回的int值來定義過濾器的執行順序,數字越小優先級越高。
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* shouldFilter:返回一個Boolean值,判斷該過濾器是否需要執行。返回true執行,返回false不執行。
* @return
*/
@Override
public boolean shouldFilter() {
return false;
}
/**
* run:編寫過濾器的具體業務邏輯。
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
return null;
}
}
二、自定義過濾器
我這里以pre
類型演示
@Component
public class LoginFilter extends ZuulFilter {
//過濾類型 pre route post error
@Override
public String filterType() {
return "pre";
}
//過濾優先級,數字越小優先級越高
@Override
public int filterOrder() {
return 10;
}
//是否執行run方法
@Override
public boolean shouldFilter() {
return true;
}
//過濾邏輯代碼
@Override
public Object run() throws ZuulException {
//獲取zuul提供的上下文對象
RequestContext context = RequestContext.getCurrentContext();
//獲取request對象
HttpServletRequest request = context.getRequest();
//獲取請求參數
String token = request.getParameter("username");
//判斷
if (StringUtils.isBlank(username)){
//過濾該請求,不對其進行路由
context.setSendZuulResponse(false);
//設置響應碼401
context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
//設置響應體
context.setResponseBody("request error....");
}
// 校驗通過,把登陸信息放入上下文信息,繼續向后執行
context.set("username",username);
return null;
}
}
沒添加過濾功能之前是這樣的 ↓,無論加不加username都可以得到數據
添加了過濾功能之后是這樣的 ↓,只有加了username才能訪問
F12打開控制台,發現響應了401
三、過濾器執行的聲明周期
-
正常流程:
- 請求到達首先會經過pre類型過濾器,而后到達route類型,進行路由,請求就到達真正的服務提供者,執行請求,返回結果后,會到達post過濾器。而后返回響應。
-
異常流程:
- 整個過程中,pre或者route過濾器出現異常,都會直接進入error過濾器,在error處理完畢后,會將請求交給POST過濾器,最后返回給用戶。
- 如果是error過濾器自己出現異常,最終也會進入POST過濾器,將最終結果返回給請求客戶端。
- 如果是POST過濾器出現異常,會跳轉到error過濾器,但是與pre和route不同的是,請求不會再到達POST過濾器了。