jwt, json web token
jwt
- 1. JWT
- 什么是JWT
- JWT能做什么
- 為什么用JWT
- JWT結構
- JWT問題和趨勢
- 2. jwt加解密工具,使用
- pom
- 工具類
- 測試
1. JWT
什么是JWT
JWT能做什么
為什么用JWT
基于傳統的session認證
求時發送給我們的應用,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統的基于session認證
認證流程
暴露的問題
sessionid就是一個特征值,表達的信息不夠豐富,不容易擴展,而且如果你后端應用是多節點部署,那么就需要實現 session共享機制,不方便集群應用
基于JWT認證
認證流程
JWT優勢
JWT結構
令牌組成
因此,JWT通常如下所示:xxx.yyy.zzz
Header
標頭通常由兩部分組成:令牌的類型(即JWT和所使用的簽名算法,例如HMAC SHA256或RSA,它會使Base64編碼組成JWT結構的第一部分。
注意:Base64是一種編碼,也就是說,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程
Payload
令牌的第二部分是有效負載,其中包含聲明,聲明是有關實體(通常是用戶)和其他數據的聲明。同樣的,它會使用Base64編碼組成
JWT結構的第二部分
Signature
前面兩部分都是使用Base64進行編碼的,即前端可以解開知道里面的信息, Signature需要使用編碼后的 header和 payload以及我們提供的一個密鑰,然后使用 header中指定的簽名算法(HS256)進行簽名,簽名的作用是保證JWT沒有被慕改過
簽名目的
最后一步簽名的過程,實際上是對頭部以及負載內容進行簽名,防止內容被竄改。如果有人對頭部以及負載的內容解碼之后進行修改,再進行編碼,最后加上之前的簽名組合形成新的JWT的話,那么服務器端會判斷出新的頭部和負載形成的簽名和JWT附帶上的簽名是不一樣的
如果要對新的頭部和負載進行簽名,在不知道服務器加密時使用的密鑰的話,得出來的簽名也是不一樣的
信息安全問題
在這里大家一定會問一個問題:Base64是一種編碼,是可逆的,那么我的信息不就被暴露了嗎?
是的。所以,在JWT中,不應該在負載里面加入任何敏感的數據。比如,我們傳輸的是用戶的 User ID,這個值實際上不是什么敏感內容,一般情況下被知道也是安全的。但是像密碼這樣的內容就不能被放在JWT中了。如果將用戶的密碼放在了JWT中,那么懷有惡意的第三方通過Base64解碼就能很快地知道你的密碼了。因此JWT適合用于向Web應用傳遞一些非敏感信息。JWT還經常用于設計用戶認證和授權系統,甚至實現web應用的單點登錄。
JWT問題和趨勢
2. jwt加解密工具,使用
pom
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt --><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.10.3</version></dependency>工具類
package top.bitqian.config;import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT;import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map;/*** @author echo lovely* @date 2020/12/4 21:46*/public class JwtUtil {//密鑰(不能泄露 、可多次加鹽加密再存在合適的地方)public static final String SECRET = "defAu&TJHVhc$%WW^JJG";//過期時間:秒public static final int EXPIRE = 300;/*** JWT 添加至HTTP HEAD中的前綴*/private static final String JWT_SEPARATOR = "Bearer ";/*** 生成Token* @param userName userName* @param userPwd userPwd* @return token token* @throws Exception create token ex*/public static String createToken(String userName, String userPwd) throws Exception {try {//日歷對象//當前時間Calendar nowTime = Calendar.getInstance();//加30秒nowTime.add(Calendar.SECOND, EXPIRE);Date expireDate = nowTime.getTime();//標頭 可以不寫,默認值就是下方所定義的mapMap<String, Object> map = new HashMap<>();// 算法map.put("alg", "HS256");// 類型 jwt加密map.put("typ", "JWT");return JWT.create().withHeader(map)//頭 有默認值 可以不寫//負載 業務數據.withClaim("userPwd", userPwd).withClaim("userName", userName).withClaim("myId", "aa").withSubject("subject")//可以不寫.withIssuedAt(new Date())//簽名時間.withExpiresAt(expireDate)//過期時間.sign(Algorithm.HMAC256(SECRET));//簽名} catch (Exception e) {throw new Exception(e);}}/*** 驗證Token* @param token token* @return token map* @throws RuntimeException 憑證已過期,請重新登錄*/public static Map<String, Claim> verifyToken(String token) throws RuntimeException {JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();DecodedJWT jwt;try {jwt = verifier.verify(token);}catch (Exception e){throw new RuntimeException("憑證已過期,請重新登錄");}return jwt.getClaims();}/*** 解析Token* @param token token* @return claim*/public static Map<String, Claim> parseToken(String token){DecodedJWT decodedJWT = JWT.decode(token);return decodedJWT.getClaims();}}測試
public static void main(String[] args){try {// 創建token,傳入參數String token = JwtUtil.createToken("your token param", "your token param");// 獲取tokenSystem.out.println("token=" + token);//Thread.sleep(5000);Map<String, Claim> map = JwtUtil.verifyToken(token);//Map<String, Claim> map = JwtUtil.parseToken(token);//遍歷for (Map.Entry<String, Claim> entry : map.entrySet()){if (entry.getValue().asString() != null){System.out.println(entry.getKey() + "===" + entry.getValue().asString());}else {System.out.println(entry.getKey() + "===" + entry.getValue().asDate());}}}catch (Exception e){e.printStackTrace();}}總結
以上是生活随笔為你收集整理的jwt, json web token的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: abap调用Linux命令,ABAP中输
- 下一篇: linux 封装python,基于lin