日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jwt, json web token

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jwt, json web token 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jwt

  • 1. JWT
    • 什么是JWT
    • JWT能做什么
    • 為什么用JWT
    • JWT結構
    • JWT問題和趨勢
  • 2. jwt加解密工具,使用
    • pom
    • 工具類
    • 測試

1. JWT

  • 什么是JWT

  • 官方定義 json web token是一個開放標準(rfc7519),它定義了一種緊湊的,自包含的方式,用于在各方之間以JSON對象安全的傳輸信息,此信息可以驗證和信任,因為它是數字簽名的。jwt可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公鑰、私鑰進行簽名。
  • 通俗解釋 JWT簡稱JSON Web Token,也就是通過JSON形式作為Web應用中的令牌,用于在各方之間安全地將信息作為JSON對象傳輸,在傳輸過程中還可以完成數據加密、簽名等相關處理。
  • JWT能做什么

  • 授權
  • 這是使用JWT的最常見的方案,一旦用戶登錄成功,系統生成一個JWT傳遞給用戶,每個后續請求將包括JWT,從而允許用戶訪問該令牌允許的路由,服務和資源。單點登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。
  • 信息交換
  • JSON Web Token是在各方之間安全的傳輸信息的好方法,因為可以對JWT進行簽名,所以您可以確保發件人是所說的人。此外,由于簽名是使用標頭和有效負載計算的,因此您還可以驗證內容是否被篡改。
  • 為什么用JWT

  • 基于傳統的session認證

  • 我們知道http協議本身是一種無狀態的協議,而這就意味著如果用戶向我們的應用提供了用戶名和密碼來進行用戶認證,那么下一次請求時,用戶還要再一次進行用戶認證才行,因為根據http協議,我們并不能知道是哪個用戶發出的請求,所以為了讓我們的應用能說明是哪個用戶發出的請求,我們只能在服務器存儲一份用戶登錄的信息,這份登錄信息會在響應時傳遞給瀏覽器,告訴其保存為 cookie,以便下次請
    求時發送給我們的應用,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統的基于session認證
  • 認證流程

  • cookie session
  • 暴露的問題

  • 每個用戶經過我們的應用認證之后,我們的應用都要在服務做一次記錄,以方便用戶下次請求的別,通常而言session都是保存在內存中,而隨著認證用戶的增多,服務器的開銷會明顯增大
  • 用戶認證之后,服務器做認證記錄,如果認證的記錄被保存在內存中的話,這意妹著用戶下次請求還必項要請求在這臺服務器上,這樣才能拿到授權的源,這樣在分布式的應用上,相應的限制了負載均衡的能力,這也意味著限制了應用的擴屬能力
  • 因為是基于 cookie來進行用戶識別的,cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊
  • 在前后端分離系統中就更加痛苦:前后端分離在應用解耦后增加了部署的復雜性,通常用戶一次請求就要轉發多次,如果用session每次攜帶 sessionid到服務器,服務器還要查詢用戶信息,如果同時用戶很多,這些信息存儲在服務器內存中,給服務器增加負擔,還有就是CSRF(跨站請求偽造的攻擊,session是基于 cookie進行用戶識別的,cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊,還有就是
    sessionid就是一個特征值,表達的信息不夠豐富,不容易擴展,而且如果你后端應用是多節點部署,那么就需要實現 session共享機制,不方便集群應用
  • 基于JWT認證

  • 認證流程
  • 認證流程

  • 首先通過表單將自己的用戶名和密碼發送到后端的接口,這一過程一般是一個HTTP POST請求,建的方式是通過SSL加密的傳輸(https協議),從而避免敏感信息被嗅探。
  • 后端核對用戶名和密碼成功后,將用戶的id等其他信息作為 JWT Payload(負載),將其與頭部分別進行bas64編碼拼接后簽名,形成一個JWT( Token),形成的JWT就是一個形同111.zzz,xxx的字符串
  • token head. payload. singurater
  • 后端將JWT作為登錄成功的返回結果返回給前端,前端可以將返回的結果保存在localStorage或sessionStorage上,退出登錄時前端刪除保存的JWT即可。
  • 前端在每次請求時將JWT放入 Http Header中的 Authorization位,(解決XSS和XSRF問題) HEADER
  • 后端檢查是否存在,如存在驗證JWT的有效性,例如,檢查簽名是否正確:檢查 Token是否過期:檢查Token的接收方是否是自己(可選)
  • 驗證通過后后端使用JWT中包含的用戶信息進行其他邏輯操作,返回相應結果。
  • JWT優勢

  • 簡潔:可以通過URL,POST參數或者在 HTTP header發送,因為數據量小,傳輸速度也很快
  • 自包含:負載中包含了所有用戶所需要的信息,避免了多次查詢數據庫
  • 因為Token是以JSON加密的形式保存在客戶端的,所以JWT是跨語言的,原則上任何web形式都支持
  • 不需要在服務器保存會話信息,特別適用于分布式微服務。
  • JWT結構

  • 令牌組成

  • 標頭( Header)
  • 有效負載( Payload)
  • 簽名( Sionature)
    因此,JWT通常如下所示:xxx.yyy.zzz
  • Header
    標頭通常由兩部分組成:令牌的類型(即JWT和所使用的簽名算法,例如HMAC SHA256或RSA,它會使Base64編碼組成JWT結構的第一部分。
    注意:Base64是一種編碼,也就是說,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程

    {"alg":"HS256","typ":"JWT" }
  • Payload
    令牌的第二部分是有效負載,其中包含聲明,聲明是有關實體(通常是用戶)和其他數據的聲明。同樣的,它會使用Base64編碼組成
    JWT結構的第二部分

    {"id":666,"name":"bitqian666","age":19 }
  • Signature
    前面兩部分都是使用Base64進行編碼的,即前端可以解開知道里面的信息, Signature需要使用編碼后的 header和 payload以及我們提供的一個密鑰,然后使用 header中指定的簽名算法(HS256)進行簽名,簽名的作用是保證JWT沒有被慕改過

  • 簽名目的
    最后一步簽名的過程,實際上是對頭部以及負載內容進行簽名,防止內容被竄改。如果有人對頭部以及負載的內容解碼之后進行修改,再進行編碼,最后加上之前的簽名組合形成新的JWT的話,那么服務器端會判斷出新的頭部和負載形成的簽名和JWT附帶上的簽名是不一樣的
    如果要對新的頭部和負載進行簽名,在不知道服務器加密時使用的密鑰的話,得出來的簽名也是不一樣的

  • 信息安全問題
    在這里大家一定會問一個問題:Base64是一種編碼,是可逆的,那么我的信息不就被暴露了嗎?
    是的。所以,在JWT中,不應該在負載里面加入任何敏感的數據。比如,我們傳輸的是用戶的 User ID,這個值實際上不是什么敏感內容,一般情況下被知道也是安全的。但是像密碼這樣的內容就不能被放在JWT中了。如果將用戶的密碼放在了JWT中,那么懷有惡意的第三方通過Base64解碼就能很快地知道你的密碼了。因此JWT適合用于向Web應用傳遞一些非敏感信息。JWT還經常用于設計用戶認證和授權系統,甚至實現web應用的單點登錄。

  • JWT問題和趨勢

  • JWT默認不加密,但可以加密。生成原始令牌后,可以使用改令牌再次對其進行加密。
  • 當JWT未加密方法時,一些私密數據無法通過JWT傳輸。
  • JWT不僅可用于認證,還可用于信息交換。善用JWT有助于減少服務器請求數據庫的次數。
  • JWT的最大缺點是服務器不保存會話狀態,所以在使用期間不可能取消令牌或更改令牌的權限。也就是說,一旦JWT簽發,在有效期內將會一直有效。
  • JWT本身包含認證信息,因此一旦信息泄露,任何人都可以獲得令牌的所有權限。為了減少盜用,JWT的有效期不宜設置太長。對于某些重要操作,用戶在使用時應該每次都進行進行身份驗證。
  • 無感刷新JWT,后端接收JWT解析獲取過期時間,如果快過期,生成新的令牌(業務數據和之前一致)
  • 為了減少盜用和竊取,JWT不建議使用HTTP協議來傳輸代碼,而是使用加密的HTTPS協議進行傳輸。
  • 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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。