SpringBootWeb登錄認(rèn)證

目錄
登錄功能
登錄校驗(yàn)(重點(diǎn))
異常處理

登錄功能
controller:
service接口:
接口實(shí)現(xiàn)類:
mapper:

問(wèn)題:在未登錄情況下,我們也可以直接訪問(wèn)部門管理、員工管理等功能。


登錄校驗(yàn)(重點(diǎn))

登錄標(biāo)記(會(huì)話技術(shù))
用戶登錄成功之后,每一次請(qǐng)求中,都可以獲取到該標(biāo)記。
統(tǒng)一攔截
過(guò)濾器Filter
攔截器Interceptor

會(huì)話技術(shù)
會(huì)話:用戶打開(kāi)瀏覽器,訪問(wèn)web服務(wù)器的資源,會(huì)話建立,直到有一方斷開(kāi)連接,會(huì)話結(jié)束。在一次會(huì)話中可以包含多次請(qǐng)求和響應(yīng)。
會(huì)話跟蹤:一種維護(hù)瀏覽器狀態(tài)的方法,服務(wù)器需要識(shí)別多次請(qǐng)求是否來(lái)自于同一瀏覽器,以便在同一次會(huì)話的多次請(qǐng)求間共享數(shù)據(jù)。
會(huì)話跟蹤方案:
客戶端會(huì)話跟蹤技術(shù):Cookie
服務(wù)端會(huì)話跟蹤技術(shù):Session
令牌技術(shù)

會(huì)話跟蹤方案對(duì)比
方案一:

優(yōu)點(diǎn):HTTP協(xié)議中支持的技術(shù)
缺點(diǎn):
?移動(dòng)端APP無(wú)法使用Cookie
?不安全,用戶可以自己禁用Cookie
?Cookie不能跨域

方案二:

優(yōu)點(diǎn):存儲(chǔ)在服務(wù)端,安全
缺點(diǎn):
?服務(wù)器集群環(huán)境下無(wú)法直接使用Session
?Cookie的缺點(diǎn)
方案三:

優(yōu)點(diǎn):
?支持PC端、移動(dòng)端
?解決集群環(huán)境下的認(rèn)證問(wèn)題
?減輕服務(wù)器端存儲(chǔ)壓力
缺點(diǎn):需要自己實(shí)現(xiàn)

JWT令牌
全稱:JSON? Web? Token (https://jwt.io/)
定義了一種簡(jiǎn)潔的、自包含的格式,用于在通信雙方以json數(shù)據(jù)格式安全的傳輸信息。由于數(shù)字簽名的存在,這些信息是可靠的。
組成:
第一部分: Header(頭),記錄令牌類型、簽名算法等。例如:{"alg":"HS256"," type" :" JWT"}
第二部分: Payload(有效載荷),攜帶一些自定義信息、默認(rèn)信息等。例如: {"id":"1", "username" :"Tom"}
第三部分:Signature(簽名),防止Token被篡改、確保安全性。將header、payload,并加入指定秘鑰,通過(guò)指定簽名算法計(jì)算而來(lái)。


場(chǎng)景:登錄認(rèn)證。
登錄成功后,生成令牌
后續(xù)每個(gè)請(qǐng)求,都要攜帶JWT令牌,系統(tǒng)在每次請(qǐng)求處理之前,先校驗(yàn)令牌,通過(guò)后,再處理。
pom.xml:
Test:
注意事項(xiàng):
JWT校驗(yàn)時(shí)使用的簽名秘鑰,必須和生成JWT令牌時(shí)使用的秘鑰是配套的。
如果JWT令牌解析校驗(yàn)時(shí)報(bào)錯(cuò),則說(shuō)明 JWT令牌被篡改 或 失效了,令牌非法。
?

登錄-生成令牌

思路:
令牌生成:登錄成功后,生成JWT令牌,并返回給前端。
令牌校驗(yàn):在請(qǐng)求到達(dá)服務(wù)端后,對(duì)令牌進(jìn)行統(tǒng)一攔截、校驗(yàn)。
步驟:
引入JWT令牌操作工具類。
登錄完成后,調(diào)用工具類生成JWT令牌,并返回。

過(guò)濾器Filter
快速入門
詳解
登錄校驗(yàn)-Filter

概念:Filter 過(guò)濾器,是 JavaWeb 三大組件(Servlet、Filter、Listener)之一。
過(guò)濾器可以把對(duì)資源的請(qǐng)求攔截下來(lái),從而實(shí)現(xiàn)一些特殊的功能。
過(guò)濾器一般完成一些通用的操作,比如:登錄校驗(yàn)、統(tǒng)一編碼處理、敏感字符處理等。


Filter快速入門
1.定義Filter:定義一個(gè)類,實(shí)現(xiàn) Filter 接口,并重寫其所有方法。
2.配置Filter:Filter類上加 @WebFilter 注解,配置攔截資源的路徑。引導(dǎo)類上加 @ServletComponentScan 開(kāi)啟Servlet組件支

小結(jié):
定義:實(shí)現(xiàn)Filter接口
配置:@WebFilter(urlPatterns="/*")
@ServletComponentScan

Filter詳解(執(zhí)行流程、攔截路徑、過(guò)濾器鏈)
Filter執(zhí)行流程:

疑問(wèn):
1.放行后訪問(wèn)對(duì)應(yīng)資源,資源訪問(wèn)完成后,還會(huì)回到Filter中嗎?會(huì)
2.如果回到Filter中,是重新執(zhí)行還是執(zhí)行放行后的邏輯呢?執(zhí)行放行后邏輯
Filter攔截路徑
Filter 可以根據(jù)需求,配置不同的攔截資源路徑:

過(guò)濾器鏈
介紹:一個(gè)web應(yīng)用中,可以配置多個(gè)過(guò)濾器,這多個(gè)過(guò)濾器就形成了一個(gè)過(guò)濾器鏈。
順序:注解配置的Filter,優(yōu)先級(jí)是按照過(guò)濾器類名(字符串)的自然排序。

小結(jié):
1.執(zhí)行流程
請(qǐng)求 --> 放行前邏輯 --> 放行 --> 資源 --> 放行后邏輯
2.攔截路徑
/login
/depts/*
/*
3.過(guò)濾器鏈
一個(gè)web應(yīng)用中,配置了多個(gè)過(guò)濾器,就形成了一個(gè)過(guò)濾器鏈

登錄校驗(yàn)-Filter

思考:
1.所有的請(qǐng)求,攔截到了之后,都需要校驗(yàn)令牌嗎?
有一個(gè)例外,登錄請(qǐng)求
2.攔截到請(qǐng)求后,什么情況下才可以放行,執(zhí)行業(yè)務(wù)操作?
有令牌,且令牌校驗(yàn)通過(guò)(合法);否則都返回未登錄錯(cuò)誤結(jié)果

登錄校驗(yàn)Filter-流程
步驟:
獲取請(qǐng)求url。
判斷請(qǐng)求url中是否包含login,如果包含,說(shuō)明是登錄操作,放行。
獲取請(qǐng)求頭中的令牌(token)。
判斷令牌是否存在,如果不存在,返回錯(cuò)誤結(jié)果(未登錄)。
解析token,如果解析失敗,返回錯(cuò)誤結(jié)果(未登錄)。
放行。


攔截器Interceptor
簡(jiǎn)介 & 快速入門
詳解
登錄校驗(yàn)- Interceptor

概念:是一種動(dòng)態(tài)攔截方法調(diào)用的機(jī)制,類似于過(guò)濾器。Spring框架中提供的,用來(lái)動(dòng)態(tài)攔截控制器方法的執(zhí)行。
作用:攔截請(qǐng)求,在指定的方法調(diào)用前后,根據(jù)業(yè)務(wù)需要執(zhí)行預(yù)先設(shè)定的代碼。

Interceptor 快速入門
1.定義攔截器,實(shí)現(xiàn)HandlerInterceptor接口,并重寫其所有方法。
2.注冊(cè)攔截器

詳解(攔截路徑、執(zhí)行流程)
攔截器可以根據(jù)需求,配置不同的攔截路徑:



Filter(過(guò)濾器) 與 Interceptor(攔截器)
接口規(guī)范不同:過(guò)濾器需要實(shí)現(xiàn)Filter接口,而攔截器需要實(shí)現(xiàn)HandlerInterceptor接口。
攔截范圍不同:過(guò)濾器Filter會(huì)攔截所有的資源,而Interceptor只會(huì)攔截Spring環(huán)境中的資源。

登錄校驗(yàn)Interceptor
步驟:
獲取請(qǐng)求url。
判斷請(qǐng)求url中是否包含login,如果包含,說(shuō)明是登錄操作,放行。
獲取請(qǐng)求頭中的令牌(token)。
判斷令牌是否存在,如果不存在,返回錯(cuò)誤結(jié)果(未登錄)。
解析token,如果解析失敗,返回錯(cuò)誤結(jié)果(未登錄)。
放行。

登錄校驗(yàn)中的過(guò)濾器和攔截器用一種就可以了,用過(guò)濾器可以,用攔截器也可以。

異常處理
程序開(kāi)發(fā)過(guò)程中不可避免的會(huì)遇到異常現(xiàn)象

出現(xiàn)異常,該如何處理?
方案一:在Controller的方法中進(jìn)行try…catch處理(代碼臃腫,不推薦)
方案二:全局異常處理器(簡(jiǎn)單、優(yōu)雅,推薦)
@RestControllerAdvice = @ControllerAdvice + @ResponseBody