SpringBoot-JWT生成Token和攔截器的使用(訪問受限資源)
1.什么是JWT
JWT官方的定義是:JSON Web令牌(JWT)是一個開放標(biāo)準(zhǔn)(RFC 7519),用于作為JSON對象在各方之間安全地傳輸信息。 可以驗證和信任該信息,因為它是數(shù)字簽名的。 jwt可以使用一個秘密(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對進(jìn)行簽名。
其實他本質(zhì)上就是一個簽名,用于驗證用戶是否可以請求受限資源(例如在商城中向服務(wù)器請求個人中心頁面信息、購物車頁面信息)
比如說現(xiàn)在在你家樓下有一家有一家自助餐廳,自助餐廳的門前有一個收銀柜臺。到了中午你感覺到肚子餓了,去了自助餐廳吃飯,去收銀柜臺交了錢,收銀柜臺給你開了一張你交過錢的證明,該證明里寫了你什么時候交的錢,交了多少錢等信息,現(xiàn)在你拿著這張證明去餐廳里面吃飯,吃飯時候只要給這張證明就行,因為他認(rèn)證了你的信息,店員知道你交過錢了也不會讓你再交一次,同時防止了你不交錢吃飯的情況。
在這個例子中,我們?nèi)绻褕鼍稗D(zhuǎn)換到網(wǎng)上商城(前后端分離的情況),收銀柜臺就是登錄,登錄完后服務(wù)器給你一個證明,證明你登錄過了,這個證明有生成的時間、你的信息等等,這時候你想訪問購物車,就拿著這個證明發(fā)給服務(wù)器,服務(wù)器驗證該證明,驗證通過后返回給你想要的數(shù)據(jù)。
還有一種情況就是如果你沒有登錄,想直接訪問購物車的數(shù)據(jù),服務(wù)器會發(fā)現(xiàn)你沒有token(或者你偽造了一個token服務(wù)器驗證不通過或者token過期),就會讓你重新登錄,從而實現(xiàn)了攔截訪問受限資源的功能。
2.JWT生成token
2.1 添加依賴
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>2.2 生成token
該案例為 在 登錄的Controller中,用戶的賬號密碼輸入正確,生成token,其中最重要的是token的密碼,驗證token時候需要使用
JwtBuilder builder = Jwts.builder();
String token = builder.setSubject("userName")
.setIssuedAt(new Date()) //設(shè)置token生成時間
.setId(u.getUserId() + "")//設(shè)置tokenID
.setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000))//設(shè)置過期時間,現(xiàn)在為設(shè)置 一天
.signWith(SignatureAlgorithm.HS256, "123456")//設(shè)置token密碼,解析token需要使用
.compact();到此token生成完畢,接著返回給前端,前端收到后將其存在cookie當(dāng)中 這里提供一個設(shè)置cookie的工具類代碼,設(shè)置或者取出cookie可以直接使用 每次前端發(fā)送請求時候都在 請求頭 中攜帶token即可
var operator = "=";
//取出cookie
function getCookieValue(keyStr){
var value = null;
var s = window.document.cookie;
var arr = s.split("; ");
for(var i=0; i<arr.length; i++){
var str = arr[i];
var k = str.split(operator)[0];
var v = str.split(operator)[1];
if(k == keyStr){
value = v;
break;
}
}
return value;
}
//設(shè)置cookie
function setCookieValue(key,value){
document.cookie = key+operator+value;
}2.3 使用攔截器解析token
配置攔截器
其中ResultVO和ResStatus為封裝的返回對象,代碼如下:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultVO {
@ApiModelProperty("響應(yīng)狀態(tài)碼")
private Integer code;
@ApiModelProperty("響應(yīng)信息")
private String msg;
@ApiModelProperty("響應(yīng)數(shù)據(jù)")
private Object Data;
}public class ResStatus {
public static Integer OK = 10000;
public static Integer NO = 10001;
public static Integer PASS = 20002;
}@Component
public class CheckTokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//因為是在請求頭中發(fā)送token,所以第一次請求的方法為"OPTIONS",具體可以看TCP/IP協(xié)議
String method = request.getMethod();
if("OPTIONS".equalsIgnoreCase(method)){
return true;
}
String token = request.getHeader("token");
System.out.println("token:"+token);
if(token == null){
ResultVO resultVO = new ResultVO(ResStatus.NO,"請先登錄",null);
doResponse(response,resultVO);
}else{
try{
//在jwt中,只要token不合法或者驗證不通過就會拋出異常
JwtParser parser = Jwts.parser();
parser.setSigningKey("123456");
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
return true;
}catch (ExpiredJwtException e1) {
ResultVO resultVO = new ResultVO(ResStatus.PASS, "登錄過期,請重新登錄", null);
doResponse(response,resultVO);
}catch (UnsupportedJwtException e2){
ResultVO resultVO = new ResultVO(ResStatus.NO, "Token不合法,已記錄惡意IP", null);
doResponse(response,resultVO);
}catch (Exception e3){
ResultVO resultVO = new ResultVO(ResStatus.NO, "請先登錄", null);
doResponse(response,resultVO);
}
}
return false;
}
@SneakyThrows
private void doResponse(HttpServletResponse response, ResultVO resultVO) {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String s = new ObjectMapper().writeValueAsString(resultVO);
out.print(s);
out.flush();
out.close();
}
}設(shè)置攔截器攔截的內(nèi)容
攔截了shopcart的請求,排除了user開頭的請求,因為user開頭請求負(fù)責(zé)登錄和注冊不應(yīng)被攔截
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Resource
private CheckTokenInterceptor checkTokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(checkTokenInterceptor)
.addPathPatterns("/shopcart/**")
.excludePathPatterns("/user/**");
}
}到此這篇關(guān)于SpringBoot-JWT生成Token和攔截器的使用(訪問受限資源)的文章就介紹到這了,更多相關(guān)SpringBoot-JWT生成Token和攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springcloud seata nacos環(huán)境搭建過程圖解
這篇文章主要介紹了Springcloud seata nacos環(huán)境搭建過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
解決spring AOP中自身方法調(diào)用無法應(yīng)用代理的問題
這篇文章主要介紹了解決spring AOP中自身方法調(diào)用無法應(yīng)用代理的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
springboot加載命令行參數(shù)ApplicationArguments的實現(xiàn)
本文主要介紹了springboot加載命令行參數(shù)ApplicationArguments的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
InterProcessMutex實現(xiàn)zookeeper分布式鎖原理
本文主要介紹了InterProcessMutex實現(xiàn)zookeeper分布式鎖原理,文中根據(jù)實例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
Java內(nèi)存模型相關(guān)知識總結(jié)
這篇文章主要介紹了Java內(nèi)存模型相關(guān)知識總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10
Java讀取制表符文本轉(zhuǎn)換為JSON實現(xiàn)實例
在Java開發(fā)中,處理各種數(shù)據(jù)格式是常見的任務(wù),本文將介紹如何使用Java讀取制表符文本文件,并將其轉(zhuǎn)換為JSON格式,以便于后續(xù)的數(shù)據(jù)處理和分析,我們將使用Java中的相關(guān)庫來實現(xiàn)這個過程,并提供詳細(xì)的代碼示例2024-01-01
Java后臺通過Collections獲取list集合中最大數(shù),最小數(shù)代碼
這篇文章主要介紹了Java后臺通過Collections獲取list集合中最大數(shù),最小數(shù)代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08

