SpringBoot整合JWT做身份驗證
本文主要參考了以下兩篇文章,如果對JWT不熟悉則可以進去了解:
- http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
- https://blog.csdn.net/qq_37636695/article/details/79265711
JWT的作用時序圖:
一、匯入JWT依賴
SpringBoot在使用JWT前需要匯入jjwt依賴:
- pom.xml
<!-- jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
二、JWTUtil
這是為JWT寫的工具類,用來生成JWT以及解析JWT,具體的作用都在程式碼中有註釋。
- JWTUtil
/**
* @Author: arong
* @Description: JWT工具
* @Date: 2019/1/19 11:05
*/
public class JWTUtils {
//用於生成secret key的stingKey
private static String JWT_SECRET = "asdfghjkl1234567890";
/*
*@author arong
*@description 建立JWT Token
*@param: claims jwt的所含的用於校驗的資訊
*@param: subject 使用者唯一標識
*@param: ttlMillis 過期時間(毫秒)
*@return java.lang.String
*@date 2019/1/19
*/
public static String createJWT(Map claims,String subject, long ttlMillis) throws Exception {
//指定簽名的時候使用的簽名演算法,也就是header那部分,jjwt已經將這部分內容封裝好了。
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//生成JWT的時間
long nowMillis = System.currentTimeMillis();
//將long型的時間毫秒轉為日期時間
Date now = new Date(nowMillis);
//生成簽名的時候使用的祕鑰secret
SecretKey key = generalKey();
//下面就是在為payload新增各種標準宣告和私有宣告瞭
JwtBuilder builder = Jwts.builder() //這裡其實就是new一個JwtBuilder,設定jwt的body
.setClaims(claims) //如果有私有宣告,一定要先設定這個自己建立的私有的宣告,這個是給builder的claim賦值,一旦寫在標準的宣告賦值之後,就是覆蓋了那些標準的宣告的
.setIssuedAt(now) //iat: jwt的簽發時間
.setSubject(subject)//一個json格式的字串作為使用者的唯一標誌。
.signWith(signatureAlgorithm, key);//設定簽名使用的簽名演算法和簽名使用的祕鑰
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp); //設定過期時間戳
}
return builder.compact();
}
/*
*@author arong
*@description 通過jwt解析得到claims資料描述物件
*@param: jwt
*@return io.jsonwebtoken.Claims
*@date 2019/1/19
*/
public static Claims parseJWT(String jwt) throws Exception{
//得到原來的簽名祕鑰,用其才能解析JWT
SecretKey key = generalKey();
//得到 DefaultJwtParser
Claims claims = Jwts.parser()
.setSigningKey(key) //設定簽名的祕鑰
.parseClaimsJws(jwt).getBody();//設定需要解析的jwt
return claims;
}
/*
*@author arong
*@description
*@param: 生成secret key
*@return javax.crypto.SecretKey
*@date 2019/1/19
*/
private static SecretKey generalKey(){
//stringKey
String stringKey = JWT_SECRET;
// 使用base64解碼
byte[] encodedKey = Base64.decodeBase64(stringKey);
// 根據給定的位元組陣列使用AES加密演算法構造一個金鑰
SecretKey secretKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return secretKey;
}
}
三、JWTInterceptor
這是JWT驗證的攔截器類,除了登陸和登出介面不需要校驗token,其他的任何介面都需要校驗前端傳來的token以確保請求的安全。
/**
* @Auther: ARong
* @Date: 2019/1/19 14:37
* @Description: JWT token 管理後臺的攔截校驗器
*/
@Component
public class JWTInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 允許跨域
response.setHeader("Access-Control-Allow-Origin", "*");
// 允許自定義請求頭token(允許head跨域)
// response.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
//後臺管理頁面產生的token
String token = request.getHeader("authorization");
//判斷是否過期
Optional.ofNullable(token)
.map(n -> {
try {
return JWTUtils.parseJWT(n);
} catch (Exception e) {
throw new RuntimeException("token不存在");
}
});
return true;
}
}
四、WebConfiguration
這個配置類用以註冊JWT攔截器
/**
* @Auther: ARong
* @Date: 2019/1/19 15:04
* @Description: JWT 的攔截器配置
*/
@Configuration
public class WebConfiguration implements WebMvcConfigurer{
//spring攔截器載入在springcontentText之前,所以這裡用@Bean提前載入。否則會導致過濾器中的@AutoWired注入為空
@Bean
JWTInterceptor jwtInterceptor(){
return new JWTInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("JWT攔截器啟動");
registry.addInterceptor(jwtInterceptor())
.excludePathPatterns("/admin/login",
"/api/login",
"/admin/logout",
"/error",
"/admin/getOnlineCount")
.addPathPatterns();
}
}
五、在登陸時產生token傳遞給前端
產生token的唯一途徑是登陸,如果token過期了也只能通過重新登陸去獲取token。
- AdminController
/**
* @param username
* @param session
* @auther: Arong
* @description: 登陸 新增session
* @return: com.iteason.anbaoli_vote_system.utils.AjaxResult
* @date: 2019/1/16 14:03
*/
@PostMapping(value = "/login")
public AjaxResult login(
@RequestParam("password") String password,
@RequestParam("username") String username,
HttpSession session
) throws Exception {
boolean isRight = adminService.checkUsernameAndPwd(username, password);
if (isRight) {
//獲取新token,過期時間為12h
String token = adminService.getToken(username);
OnlineCount.getInstance().insertToken(token);
Map map = new HashMap<String, Integer>();
map.put("username", username);
map.put("token", token);
return new AjaxResult().ok(map);
}
return new AjaxResult().error("使用者名稱或密碼錯誤,請重新輸入");
}
- AdminServiceImp
@Override
public String getToken(String username) {
//存入JWT的payload中生成token
Map claims = new HashMap<String,Integer>();
claims.put("admin_username",username);
String subject = "admin";
String token = null;
try {
//該token過期時間為12h
token = JWTUtils.createJWT(claims, subject, 1000*60*60*12 );
} catch (Exception e) {
throw new RuntimeException("建立Token失敗");
}
System.out.println("token:"+token);
return token;
}
相關文章
- SpringBoot 整合 JWT 實現 token 驗證,token 登出Spring BootJWT
- 使用JWT做RESTful API的身份驗證-Go語言實現JWTRESTAPIGo
- asp.core 同時相容JWT身份驗證和Cookies 身份驗證兩種模式JWTCookie模式
- AngularJS 如何做身份驗證AngularJS
- node學習---jwt實現驗證使用者身份JWT
- springboot+jwt做api的token認證Spring BootJWTAPI
- springboot整合shiro實現身份認證Spring Boot
- javascript 驗證身份證JavaScript
- 身份證如何查驗真偽?C#身份證二要素、三要素介面整合C#
- 使用 JWT 身份驗證保護你的 Spring Boot 應用JWTSpring Boot
- 使用 JWT 認證使用者身份JWT
- Laravel jwt 驗證LaravelJWT
- SpringBoot 整合SpringSecurity JWTSpring BootGseJWT
- WEB身份驗證Web
- 身份證驗證工具類
- go-kit微服務:JWT身份認證Go微服務JWT
- PHP 使用 jwt 使用者身份認證PHPJWT
- jwt驗證的思考JWT
- asp.net core 3.1多種身份驗證方案,cookie和jwt混合認證授權ASP.NETCookieJWT
- SpringBoot - 整合Auth0 JWTSpring BootJWT
- 教你 Shiro + SpringBoot 整合 JWTSpring BootJWT
- Oracle的身份驗證Oracle
- PHP 驗證身份證號碼PHP
- 中國身份證號驗證庫
- C++身份證號驗證C++
- C#驗證身份證號C#
- JWT身份認證(附帶原始碼講解)JWT原始碼
- 在 SpringBoot 專案中簡單實現 JWT 驗證Spring BootJWT
- Spring Security 6.3基於JWT身份驗證與授權開源專案SpringJWT
- SpringBoot整合Spring security JWT實現介面許可權認證Spring BootJWT
- 教你Shiro+SpringBoot整合JWTSpring BootJWT
- C++身份核驗介面程式碼、身份證OCR、身份證實名認證APIC++API
- 作業系統身份驗證和口令檔案身份驗證總結作業系統
- Spring Boot中的Firebase身份驗證+Firestore整合原始碼Spring BootREST原始碼
- js正則驗證身份證號JS
- PHP 身份證精確匹配驗證PHP
- 身份證號碼驗證系統
- 身份證號碼之js驗證JS