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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西

發布時間:2025/3/19 HTML 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JSON Web Token(縮寫 JWT)是目前最流行,也是最常見的跨域認證解決方案。無論是咱們后端小伙伴,還是前端小伙伴對都是需要了解。
本文介紹它的原理、使用場景、用法。

關于封面:這個冬天你過得開心嗎

一、跨域認證的問題

1.1、常見的前后端認證方式

  • Session-Cookie
  • Token 驗證(包括JWT,SSO)
  • OAuth2.0(開放授權)

1.2、Session-Cookie實現方式

流程大致如下:

1、用戶向服務器發送用戶名和密碼。

2、服務器驗證通過后,在當前對話(session)里面保存相關數據,比如用戶角色、登錄時間等等。

3、服務器向用戶返回一個 session_id,寫入用戶的 Cookie。

4、用戶隨后的每一次請求,都會通過 Cookie,將 session_id傳回服務器。

5、服務器收到 session_id,找到前期保存的數據,由此得知用戶的身份。

這種模式在單機時不存在什么問題,但是一旦服務器變為集群模式時,或者是跨域的服務器時,這個時候Session就必須實現數據共享。

這個時候就要考慮每臺服務器如何實現對 Session 的數據共享呢??

  • 第一種解決方式就是實現 Session 數據的持久化。各種服務收到請求時,都向數據持久層請求數據,來驗證是否是正確的用戶。但其實無論我們將 Session 存放在服務器哪里,都會增加服務器的負擔。這種方案優點就是簡單,缺點就是擴展性不好,安全性較差,容易增加服務器的負擔。
  • 第二種解決方式其實就是 JWT 的方式實現的,所有的數據不在保存到服務器端,而是保存到客戶端,每次請求時都攜帶上 Token 令牌。

  • 二、什么是 JWT ?

    根據官網介紹:

    JSON Web Token (JWT) 是一個開放標準,它定義了一種緊湊且自包含的方式,用于在各方之間作為 JSON 對象安全地傳輸信息。該信息可以被驗證和信任,因為它是經過數字簽名的。JWT 可以使用秘密(使用HMAC算法)或使用RSAECDSA的公鑰/私鑰對進行簽名

    簡單來理解就是 JWT 就是一個JSON對象經過加密和簽名的,可以在網絡中安全的傳輸信息,并且可以被驗證和信任。

    2.1、什么時候應該使用 JWT ?

    我目前用的最多的地方就是在授權方面,這也是 JWT 最常見的場景,其次還可以用來交換信息。

    授權例子:

    用戶登錄后,服務器端返回一個JWT,用戶保存在本地,之后的每次請求都將包含JWT,服務器驗證用戶攜帶的JWT,來判斷是否允許訪問服務和資源。

    另外,單點登錄(SSO) 也是當今廣泛使用JWT的一項功能,就是在A網站登錄后,在B網站也能夠實現自動登錄,而不需要重復登錄,如你在淘寶登錄了,在身份沒有過期前,你去看天貓網站,也會發現你已經登錄了。

    簡而言之:用戶只需要登錄一次就可以訪問所有相互信任的應用系統。并且能夠輕松跨不同域使用,服務器也不需要存儲session相關信息,減輕了負擔

    2.2、JWT 原理

    其實 JWT 的原理就是,服務器認證以后,將一個 JSON 對象加密成一個緊湊的字符串(Token),發回給用戶,就像下面這樣。

    // JSON 對象 {"姓名": "王五","角色": "管理員","到期時間": "2021年9月21日0點0分" } //加密后 eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VybmFtZSIsIm5iZiI6MTYzMjI3NzU1NCwiaXNzIjoiY3J1c2giLCJleHAiOjE2MzIyNzc2NTQsImRlbW8iOiLlj6_lrZjlgqjkv6Hmga8iLCJpYXQiOjE2MzIyNzc1NTQsImRlbW8yIjoi5Y-v5a2Y5YKo5L-h5oGvMiJ9.OuqG5Ha_Ofmh5R9Et1vqLYSAlIO85oW9D9Jq9cKKYODO643ZLiDTyQs8dl3PLsZ-_5t0xv6kfKhCzCkCYznBNA

    在認證之后,用戶和服務器通信時,每次都會攜帶上這個Token。服務器端不再存儲session信息,完全依靠用戶攜帶的Token來判斷用戶身份。為了安全,服務器在生成Token的時候,都會加上一個數字簽名。

    這樣做的優勢:服務器不需要再保存 session數據,減輕了服務器負擔,并且基于 JWT 認證機制的應用不需要去考慮用戶在哪一臺服務器登錄,為應用的擴展提供了便利。

    2.3、JWT 數據結構

    JSON Web Tokens 由用點 ( .)分隔的三個部分組成,它們是:

    • Header(頭部)
    • Payload(負載)
    • Signature(簽名)

    因此,JWT 通常如下所示。注意:實際上是未分行的,這里是為了便于展示。

    xxxxx.yyyyy.zzzzz 如: eyJhbGciOiJIUzUxMiJ9. eyJzdWIiOiJ1c2VybmFtZSIsIm5iZiI6MTYzMjI3NzU1NCwiaXNzIjoiY3J1c2giLCJleHAiOjE2MzIyNzc2NTQsImRlbW8iOiLlj6_lrZjlgqjkv6Hmga8iLCJpYXQiOjE2MzIyNzc1NTQsImRlbW8yIjoi5Y-v5a2Y5YKo5L-h5oGvMiJ9. OuqG5Ha_Ofmh5R9Et1vqLYSAlIO85oW9D9Jq9cKKYODO643ZLiDTyQs8dl3PLsZ-_5t0xv6kfKhCzCkCYznBNA

    2.3.1、Header (標題)

    jwt的頭部承載兩部分信息:

    • 聲明類型,這里是jwt
    • 聲明加密的算法 通常直接使用 HMAC SHA256

    Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常是下面的樣子。

    { "alg": "HS256", "typ": "JWT" }

    上面代碼中,alg屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌統一寫為JWT。

    2.3.2、Payload(有效載荷)

    Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的數據。JWT 規定了7個官方字段,供選用。

    • iss (issuer):簽發人
    • exp (expiration time):過期時間
    • sub (subject):主題 jwt所面向的用戶
    • aud (audience):受眾 接收jwt的一方
    • nbf (Not Before):生效時間
    • iat (Issued At):簽發時間
    • jti (JWT ID):編號,jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。

    除了官方字段,你還可以在這個部分定義私有字段,下面就是一個例子。

    {"sub": "1234567890","name": "John Doe","admin": true }

    注意,JWT 默認是不加密的,任何人都可以讀到,所以不要把秘密信息放在這個部分。

    2.3.3、Signature(簽名)

    Signature 部分是對前兩部分的簽名,防止數據篡改。

    首先,需要指定一個密鑰(secret)。這個密鑰只有服務器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產生簽名。

    HMACSHA256 (base64UrlEncode(header) + "." +base64UrlEncode(payload),secret )

    算出簽名以后,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,就可以返回給用戶。

    注意:簽名用于驗證消息在此過程中沒有更改,并且在使用私鑰簽名的令牌的情況下,它還可以驗證 JWT 的發送者是它所說的人。secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證的關鍵,所以,它就是我們服務端的私鑰,在任何場景都不應該泄露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了,那么安全將不復存在。

    2.3.4、 Base64URL

    前面提到,Header 和 Payload 串型化的算法是 Base64URL。這個算法跟 Base64 算法基本類似,但有一些小的不同。

    JWT 作為一個令牌(token),有些場合可能會 放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字符+、/和=,在 URL 里面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL 算法。

    2.4、JWT工具類

    相關依賴:

    <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.0</version> </dependency>

    如果是Jdk11使用的話,可能會報這樣的一個錯誤:

    Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverterat io.jsonwebtoken.impl.Base64Codec.decode(Base64Codec.java:26)at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:99)at com.crush.jwt.utils.JwtUtils.createJwt(JwtUtils.java:47)at com.crush.jwt.utils.JwtUtils.main(JwtUtils.java:127) Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverterat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)... 4 more

    好像是因為Jdk11中沒有這個類了,得加上下面這樣的一個依賴:

    <dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.0</version> </dependency>

    工具類

    import io.jsonwebtoken.*;import java.util.Date; import java.util.HashMap;/*** @Author: crush* @Date: 2021-09-21 22:18* version 1.0*/ public class JwtUtils {/*** 服務器端密鑰*/private static final String SECRET = "jwtsecretdemo";/*** 頒發者*/private static final String ISS = "crush";/*** 這里創建用到的時間、用戶名、應該是傳入進來的,* 登錄時選擇是否記住我,過期時間應當是不一致的。* @return*/public static String createJwt() {HashMap<String, Object> map = new HashMap<>();map.put("demo", "可存儲信息");map.put("demo2","可存儲信息2");String jwt = Jwts.builder().setClaims(map)// jwt所面向的用戶.setSubject("username")//設置頒發者.setIssuer(ISS)// 定義在什么時間之前,該jwt都是不可用的..setNotBefore(new Date())//簽發時間.setIssuedAt(new Date())//設置 JWT 聲明exp (到期)值.setExpiration(new Date(System.currentTimeMillis() + 100000)).signWith(SignatureAlgorithm.HS512, SECRET)//實際構建 JWT 并根據JWT 緊湊序列化 規則將其序列化為緊湊的、URL 安全的字符串。.compact();return jwt;}/*** 獲取 Claims 實例* Claims :一個 JWT聲明集 。* 這最終是一個 JSON 映射,可以向其中添加任何值,但為了方便起見,JWT 標準名稱作為類型安全的 getter 和 setter 提供。* 因為這個接口擴展了Map&lt;String, Object&gt; , 如果您想添加自己的屬性,只需使用 map 方法,* 例如:* claims.put("someKey", "someValue");** @param jwt* @return*/public static Claims getBody(String jwt) {return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(jwt).getBody();}/*** 判斷 JWT 是否已過期** @param jwt* @return*/public static boolean isExpiration(String jwt) {return getBody(jwt)//返回 JWT exp (到期)時間戳,如果不存在則返回null 。.getExpiration()//測試此日期是否在指定日期之前。.before(new Date());}/*** Subject:獲取 jwt 所面向的用戶** @param jwt* @return*/public static String getSubject(String jwt) {return getBody(jwt).getSubject();}/*** Issuer:獲取頒發者** @param jwt* @return*/public static String getIssuer(String jwt) {return getBody(jwt).getIssuer();}/*** getClaimsValue** @param jwt* @return*/public static String getClaimsValue(String jwt) {return (String) getBody(jwt).get("demo");}/*** getClaimsValue** @param jwt* @return*/public static String getClaimsValue2(String jwt) {return (String) getBody(jwt).get("demo2");}public static void main(String[] args) {String jwt = createJwt();System.out.println(jwt);System.out.println("jwt 是否已經過期:"+isExpiration(jwt));System.out.println("Claims 中所存儲信息:"+getBody(jwt).toString());System.out.println("jwt 所面向的用戶:"+getSubject(jwt));System.out.println("jwt 頒發者:"+getIssuer(jwt));System.out.println("通過鍵值,取出我們自己放進 Jwt 中的信息:"+getClaimsValue(jwt));System.out.println("通過鍵值,取出我們自己放進 Jwt 中的信息2:"+getClaimsValue2(jwt));} }

    三、如何應用

    此后,客戶端每次與服務器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面。

    Authorization: Bearer <token>

    一般是在請求頭里加入Authorization,并加上Bearer標注:

    fetch('api/user/1', {headers: {'Authorization': 'Bearer ' + token} })

    服務端會驗證token,如果驗證通過就會返回相應的資源。整個流程就是這樣的:

    實際使用過程中,我們通常是結合著Security安全框架一起使用的,大家感興趣的話,可以來一起看看我寫的這篇文章。

    SpringBoot整合Security安全框架、控制權限

    也可以直接看源碼:Security-Gitee

    四、總結

    4.1、優點:

    • 因為json的通用性,JWT支持多語言,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
    • 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
    • 可以用于交換信息。有效使用 JWT,可以降低服務器查詢數據庫的次數。
    • 便于傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便于傳輸的。
    • 它不需要在服務端保存會話信息, 所以它易于應用的擴展

    4.2、安全相關:

    • 保護好secret私鑰,該私鑰非常重要。如果密鑰泄露,用戶自己即可頒布JWT令牌,安全將不復存在。
    • 如果條件允許,JWT 不應該使用 HTTP 協議明碼傳輸,而是要使用 HTTPS 協議傳輸。Https協議更安全。
    • JWT 的有效期應該設置得比較短。對于一些比較重要的權限,使用時應該再次對用戶進行認證。

    4.3、缺點:

    • JWT 的最大優點是不需要在服務端保存會話信息,最大的缺點也是如此,由于服務器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的權限。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效。

    五、自言自語

    本文就是簡單介紹了,具體使用具體情況具體分析啦。

    你好,我是博主寧在春:主頁

    希望本篇文章能讓你感到有所收獲!!!

    祝 我們:待別日相見時,都已有所成。

    參考

    jwt

    JSON Web Token 入門教程

    總結

    以上是生活随笔為你收集整理的JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 无码日韩人妻精品久久蜜桃 | 国产成人综合网 | 亚洲黄网av | 亚洲一区二区免费电影 | 99视频+国产日韩欧美 | 青青艹在线观看 | 精品蜜桃一区二区三区 | 九九看片| 精品一区二区三区精华液 | 欧美不卡在线观看 | 91五月天 | 亚洲伦理在线视频 | 免费荫蒂添的好舒服视频 | 日本在线免费 | 在线免费视频 | 日本狠狠爱 | 日韩中文字幕一区二区三区四区 | 夜夜操操| 黄色av日韩 | 涩涩涩999| 日韩成人三级 | 亚洲国产精品18久久久久久 | 麻豆精品在线视频 | av资源网在线| 懂色av粉嫩av蜜乳av | 国产综合视频在线观看 | 成年人免费在线视频 | 91涩漫成人官网入口 | 亚洲精品一区三区三区在线观看 | 亚洲一区二区三区四区不卡 | 中文字幕资源网 | 久久久这里有精品 | 中文字幕亚洲精品在线 | 国产精品久久中文字幕 | 狠狠操一区二区 | 玉女心经 在线 | 天天看天天摸天天操 | 国产精品视频一区二区三区不卡 | 激情福利视频 | 阿v天堂在线观看 | 成长快手短视频在线观看 | 草草福利视频 | 午夜日韩在线观看 | 动漫美女舌吻 | 男人的天堂视频在线观看 | 成年丰满熟妇午夜免费视频 | 91成人破解版 | 少妇2做爰bd在线意大利堕落 | 亚洲av无码专区在线 | 青青草免费看 | 黑色丝袜吻戏亲胸摸腿 | 美日韩在线观看 | 国产精品一卡二卡三卡 | 噜噜噜av| avav我爱av | 国产美女作爱全过程免费视频 | 四虎国产| 国产国产精品 | 中文在线一区二区 | 香蕉久久一区二区三区 | 麻豆传媒在线视频 | 99riav在线 | 国产男女猛烈无遮挡免费视频动漫 | 亚洲风情第一页 | 国产精品99久久久久久大便 | 五月天男人天堂 | 亚洲精品7777 | 亚洲av无码久久精品狠狠爱浪潮 | 国产精品1区2区3区4区 | 草碰在线| 国产精品羞羞答答在线 | 一级黄色在线播放 | 日本一区二区三区在线观看视频 | 69精品丰满人妻无码视频a片 | 9999精品| 一区二区三区四区在线视频 | 一级片视频免费看 | 91网国产 | 黄色片视频 | 国产精品主播一区二区 | 国产经典久久 | 国产一级片一区二区 | 男人天堂视频在线观看 | 精品无码成人久久久久久免费 | 69天堂 | 日韩黄色大片 | 国产精品视频免费网站 | 黄色片子免费看 | 天天摸天天碰 | 国产99久久久国产精品 | 日本做爰三级床戏 | 色婷婷导航 | 欧美成人精品网站 | 受虐m奴xxx在线观看 | 天天操天天舔天天干 | 日韩美女在线 | 国产日韩欧美精品在线 | 日本一区免费 | 一区二区国产在线观看 |