JWT令牌生成后,客戶端發(fā)的請求頭中會帶有JWT令牌,服務(wù)端需要校驗每個請求的令牌,如果在每個controller方法中添加校驗?zāi)K,則十分復(fù)雜且冗余,所以引入統(tǒng)一攔截模塊,將請求攔截下來并做校驗,這塊內(nèi)容可以選擇兩種技術(shù):
-
Filter過濾器
-
Interceptor攔截器
我們首先來學(xué)習(xí)過濾器Filter。
什么是過濾器
什么是Filter?
-
Filter表示過濾器,是 JavaWeb三大組件(Servlet、Filter、Listener)之一。
-
過濾器可以把對資源的請求攔截下來,從而實現(xiàn)一些特殊的功能
-
使用了過濾器之后,要想訪問web服務(wù)器上的資源,必須先經(jīng)過濾器,過濾器處理完畢之后,才可以訪問對應(yīng)的資源。
-
-
過濾器一般完成一些通用的操作,比如:登錄校驗、統(tǒng)一編碼處理、敏感字符處理等。
?
Filter詳解
下面我們通過Filter快速入門程序掌握過濾器的基本使用操作:
-
第1步,定義過濾器 :1.定義一個類,實現(xiàn) Filter 接口,并重寫其所有方法。
-
第2步,配置過濾器:Filter類上加 @WebFilter 注解,配置攔截資源的路徑。引導(dǎo)類上加 @ServletComponentScan 開啟Servlet組件支持。
@WebFilter(urlPatterns = "/*") //配置過濾器要攔截的請求路徑( /* 表示攔截瀏覽器的所有請求 )
public class DemoFilter implements Filter {
@Override //初始化方法, 只調(diào)用一次
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init 初始化方法執(zhí)行了");
}
@Override //攔截到請求之后調(diào)用, 調(diào)用多次
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Demo 攔截到了請求...放行前邏輯");
//放行
chain.doFilter(request,response);
}
@Override //銷毀方法, 只調(diào)用一次
public void destroy() {
System.out.println("destroy 銷毀方法執(zhí)行了");
}
}
當(dāng)我們在Filter類上面加了@WebFilter注解之后,接下來我們還需要在啟動類上面加上一個注解@ServletComponentScan,通過這個@ServletComponentScan注解來開啟SpringBoot項目對于Servlet組件的支持。
@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {
?
? ?public static void main(String[] args) {
? ? ? ?SpringApplication.run(TliasWebManagementApplication.class, args);
? }
?
}
注意事項:
在過濾器Filter中,如果不執(zhí)行放行操作,將無法訪問后面的資源。 放行操作:chain.doFilter(request, response);
現(xiàn)在我們已完成了Filter過濾器的基本使用,下面我們將學(xué)習(xí)Filter過濾器在使用過程中的一些細(xì)節(jié)。
執(zhí)行流程
首先我們先來看下過濾器的執(zhí)行流程:
doFilter方法:
放行前代碼
放行:filterChain.doFilter(servletRequest,servletResponse)
放行后代碼
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
@Override //初始化方法, 只調(diào)用一次
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init 初始化方法執(zhí)行了");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("DemoFilter 放行前邏輯.....");
//放行請求
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("DemoFilter 放行后邏輯.....");
}
@Override //銷毀方法, 只調(diào)用一次
public void destroy() {
System.out.println("destroy 銷毀方法執(zhí)行了");
}
}
攔截路徑
在過濾器實現(xiàn)類上的注解@WebFilter中配置不同的攔截資源路徑:
攔截路徑 | urlPatterns值 | 含義 |
---|---|---|
攔截具體路徑 | /login | 只有訪問 /login 路徑時,才會被攔截 |
目錄攔截 | /emps/* | 訪問/emps下的所有資源,都會被攔截 |
攔截所有 | /* | 訪問所有資源,都會被攔截 |
?過濾器鏈
最后我們在來介紹下過濾器鏈,什么是過濾器鏈呢?所謂過濾器鏈指的是在一個web應(yīng)用程序當(dāng)中,可以配置多個過濾器,多個過濾器就形成了一個過濾器鏈。
以注解方式配置的Filter過濾器,它的執(zhí)行優(yōu)先級是按時過濾器類名的自動排序確定的,類名排名越靠前,優(yōu)先級越高。 ?
登錄校驗應(yīng)用
大概清楚了在Filter過濾器的實現(xiàn)步驟了,那在正式開發(fā)登錄校驗過濾器之前,我們思考兩個問題:
-
所有的請求,攔截到了之后,都需要校驗令牌嗎?
-
答案:登錄請求例外
-
-
攔截到請求后,什么情況下才可以放行,執(zhí)行業(yè)務(wù)操作?
-
答案:有令牌,且令牌校驗通過(合法);否則都返回未登錄錯誤結(jié)果文章來源:http://www.zghlxwxcb.cn/news/detail-854802.html
-
文章來源地址http://www.zghlxwxcb.cn/news/detail-854802.html
@Slf4j
@WebFilter(urlPatterns = "/*") //攔截所有請求
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
//前置:強(qiáng)制轉(zhuǎn)換為http協(xié)議的請求對象、響應(yīng)對象 (轉(zhuǎn)換原因:要使用子類中特有方法)
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1.獲取請求url
String url = request.getRequestURL().toString();
log.info("請求路徑:{}", url); //請求路徑:http://localhost:8080/login
//2.判斷請求url中是否包含login,如果包含,說明是登錄操作,放行
if(url.contains("/login")){
chain.doFilter(request, response);//放行請求
return;//結(jié)束當(dāng)前方法的執(zhí)行
}
//3.獲取請求頭中的令牌(token)
String token = request.getHeader("token");
log.info("從請求頭中獲取的令牌:{}",token);
//4.判斷令牌是否存在,如果不存在,返回錯誤結(jié)果(未登錄)
if(!StringUtils.hasLength(token)){
log.info("Token不存在");
Result responseResult = Result.error("NOT_LOGIN");
//把Result對象轉(zhuǎn)換為JSON格式字符串 (fastjson是阿里巴巴提供的用于實現(xiàn)對象和json的轉(zhuǎn)換工具類)
String json = JSONObject.toJSONString(responseResult);
response.setContentType("application/json;charset=utf-8");
//響應(yīng)
response.getWriter().write(json);
return;
}
//5.解析token,如果解析失敗,返回錯誤結(jié)果(未登錄)
try {
JwtUtils.parseJWT(token);
}catch (Exception e){
log.info("令牌解析失敗!");
Result responseResult = Result.error("NOT_LOGIN");
//把Result對象轉(zhuǎn)換為JSON格式字符串 (fastjson是阿里巴巴提供的用于實現(xiàn)對象和json的轉(zhuǎn)換工具類)
String json = JSONObject.toJSONString(responseResult);
response.setContentType("application/json;charset=utf-8");
//響應(yīng)
response.getWriter().write(json);
return;
}
//6.放行
chain.doFilter(request, response);
}
}
<dependency>
? ? <groupId>com.alibaba</groupId>
? ? <artifactId>fastjson</artifactId>
? ? <version>1.2.76</version>
</dependency>?
到了這里,關(guān)于SpringBoot登錄校驗(四)過濾器Filter的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!