目前傳統的后臺管理系統,以及不使用第三方登錄的系統,使用 JWT 技術的還是挺多的,因此在面試中被問到的頻率也比較高,所以今天我們就來看一下:什么是 JWT?為什么要用 JWT?
JWT(JSON Web Token)是一種開放標準(RFC 7519),用于在網絡上安全傳輸信息的簡潔、自包含的方式。它通常被用于身份驗證和授權機制。JWT 由三部分組成:頭部(Header)、載荷(Payload)和簽名(Signature)。
“
JWT 官網:https://jwt.io/
”
JWT 相較于傳統的基于會話(Session)的認證機制,具有以下優勢:
總結來說,使用 JWT 相較于傳統的基于會話的認證機制,可以減少服務器存儲開銷和管理復雜性,實現跨域支持和水平擴展,并且更適應無狀態和微服務架構。
在 Java 開發中,可以借助 JWT 工具類來方便的操作 JWT,例如 HuTool 框架中的 JWTUtil。
HuTool 介紹:https://doc.hutool.cn/pages/JWTUtil/
使用 HuTool 操作 JWT 的步驟如下:
在 pom.xml 中添加以下信息:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version></dependency>
Map<String, Object> map = new HashMap<String, Object>() {private static final long serialVersionUID = 1L;{ put("uid", Integer.parseInt("123")); // 用戶ID put("expire_time", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); // 過期時間15天}};JWTUtil.createToken(map, "服務器端秘鑰".getBytes());
驗證 Token 的示例代碼如下:
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJhZG1pbiIsInNjb3BlIjpbImFsbCJdLCJleHAiOjE2MjQwMDQ4MjIsInVzZXJJZCI6MSwiYXV0aG9yaXRpZXMiOlsiUk9MRV_op5LoibLkuozlj7ciLCJzeXNfbWVudV8xIiwiUk9MRV_op5LoibLkuIDlj7ciLCJzeXNfbWVudV8yIl0sImp0aSI6ImQ0YzVlYjgwLTA5ZTctNGU0ZC1hZTg3LTVkNGI5M2FhNmFiNiIsImNsaWVudF9pZCI6ImhhbmR5LXNob3AifQ.aixF1eKlAKS_k3ynFnStE7-IRGiD5YaqznvK2xEjBew";JWTUtil.verify(token, "123456".getBytes());
解析 Token 的示例代碼如下:
String rightToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiYWRtaW4iOnRydWUsIm5hbWUiOiJsb29seSJ9.U2aQkC2THYV9L0fTN-yBBI7gmo5xhmvMhATtu8v0zEA";final JWT jwt = JWTUtil.parseToken(rightToken);jwt.getHeader(JWTHeader.TYPE);jwt.getPayload("sub");
在登錄成功之后,生成 Token 的示例代碼如下:
// 登錄成功,使用 JWT 生成 TokenMap<String, Object> payload = new HashMap<String, Object>() { private static final long serialVersionUID = 1L; { put("uid", userinfo.getUid()); put("manager", userinfo.getManager()); // JWT 過期時間為 15 天 put("exp", System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 15); }};String token = JWTUtil.createToken(payload, AppVariable.JWT_KEY.getBytes());
例如在 Spring Cloud Gateway 網關中驗證 Token 的實現代碼如下:
import cn.hutool.jwt.JWT;import cn.hutool.jwt.JWTUtil;import com.example.common.AppVariable;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.List;/** * 登錄過濾器(登錄判斷) */@Componentpublic class AuthFilter implements GlobalFilter, Ordered { // 排除登錄驗證的 URL 地址 private String[] skipAuthUrls = {"/user/add", "/user/login"}; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 當前請求的 URL String url = exchange.getRequest().getURI().getPath(); for (String item : skipAuthUrls) { if (item.equals(url)) { // 繼續往下走 return chain.filter(exchange); } } ServerHttpResponse response = exchange.getResponse(); // 登錄判斷 List<String> tokens = exchange.getRequest().getHeaders().get(AppVariable.TOKEN_KEY); if (tokens == null || tokens.size() == 0) { // 當前未登錄 response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } // token 有值 String token = tokens.get(0); // JWT 效驗 token 是否有效 boolean result = false; try { result = JWTUtil.verify(token, AppVariable.JWT_KEY.getBytes()); } catch (Exception e) { result = false; } if (!result) { // 無效 token response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } else { // 判斷 token 是否過期 final JWT jwt = JWTUtil.parseToken(token); // 得到過期時間 Object expObj = jwt.getPayload("exp"); if (expObj == null) { response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } long exp = Long.parseLong(expObj.toString()); if (System.currentTimeMillis() > exp) { // token 過期 response.setStatusCode(HttpStatus.UNAUTHORIZED); return response.setComplete(); } } return chain.filter(exchange); } @Override public int getOrder() { // 值越小越早執行 return 1; }}
JWT 本質是將秘鑰存放在服務器端,并通過某種加密手段進行加密和驗證的機制。加密簽名=某加密算法(header+payload+服務器端私鑰),因為服務端私鑰別人不能獲取,所以 JWT 能保證自身其安全性。
JWT 相比與傳統的 Session 會話機制,具備無狀態性(無需服務器端存儲會話信息),并且它更加靈活、更適合微服務環境下的登錄和授權判斷。JWT 是由三部分組成的:Header(頭部)、Payload(數據載荷)和 Signature(簽名)。
本文鏈接:http://www.www897cc.com/showinfo-26-38494-0.html面試官:什么是JWT?為什么要用JWT?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 面試官:什么是JWT?為什么要用JWT?