最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

JWT | 一分鐘掌握J(rèn)WT | 概念及實(shí)例

2023-08-17 20:45 作者:我要吃那朵棉花糖  | 我要投稿

什么是JWT

JWT的全稱是Json Web Token。是基于RFC 7519開(kāi)放標(biāo)準(zhǔn)的,它定義了一種緊湊且獨(dú)立的方式,用于在各方之間以 JSON 對(duì)象的形式安全地傳輸信息。此信息可以用作驗(yàn)證和相互信任,因?yàn)樗墙?jīng)過(guò)數(shù)字簽名的。JWT 可以使用密鑰(使用 HMAC 算法)或使用 RSAECDSA 的公鑰/私鑰對(duì)進(jìn)行簽名。

哪里能用JWT

以下是JWT兩種使用場(chǎng)景:

  • 授權(quán):這是使用 JWT 的最常見(jiàn)的使用場(chǎng)景。用戶登錄后,每個(gè)后續(xù)請(qǐng)求都將包含 JWT,允許用戶訪問(wèn)使用該令牌允許的路由、服務(wù)和資源。單點(diǎn)登錄是當(dāng)今廣泛使用 JWT 的一項(xiàng)功能,因?yàn)樗拈_(kāi)銷(xiāo)很小,并且能夠跨不同域輕松使用。

  • 信息交換:JWT是在各方之間安全傳輸信息的比較便捷的方式。由于 JWT 可以簽名(例如,使用公鑰/私鑰對(duì)),因此可以確定發(fā)送者是否是在您的授權(quán)范圍之內(nèi)。并且,由于簽名是使用標(biāo)頭和有效負(fù)載計(jì)算的,因此還可以驗(yàn)證內(nèi)容是否未被篡改。

JWT的組成

這是一個(gè)JWT的token串:

java復(fù)制代碼eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

很復(fù)雜,看不懂是不是?其實(shí)這一串是經(jīng)過(guò)加密之后的密文字符串,中間通過(guò).來(lái)分割。每個(gè).之前的字符串分別表示JWT的三個(gè)組成部分:Header、PayloadSignature。

Header(頭信息)

Header的主要作用是用來(lái)標(biāo)識(shí)。通常是兩部分組成:

  • typ:type 的簡(jiǎn)寫(xiě),令牌類(lèi)型,也就是JWT。

  • alg:Algorithm 的簡(jiǎn)寫(xiě),加密簽名算法。一般使用HS256,jwt官網(wǎng)提供了12種的加密算法,截圖如下:

Header的明文示例:

json復(fù)制代碼{ ??"alg": "HS256", ??"typ": "jwt" }

經(jīng)過(guò)Base64編碼之后的明文,變?yōu)椋?/p>

java復(fù)制代碼eyJhbGciOiJIUzI1NiIsInR5cCI6Imp3dCJ9

也就是第一個(gè).之前的密文串。以下是Header部分常用部分的聲明:

keyname說(shuō)明typ令牌類(lèi)型如果存在,則必須將其設(shè)置為已注冊(cè)的 IANA 媒體類(lèi)型。cty內(nèi)容類(lèi)型如果使用嵌套簽名或加密,建議將其設(shè)置為 ;否則,請(qǐng)省略此字段。alg消息身份驗(yàn)證代碼算法發(fā)行者可以自由設(shè)置算法來(lái)驗(yàn)證令牌上的簽名。但是,某些受支持的算法不安全。kid密鑰標(biāo)識(shí)指示客戶端用于生成令牌簽名的密鑰的提示。服務(wù)器將此值與文件上的密鑰匹配,以驗(yàn)證簽名是否有效以及令牌是否真實(shí)。x5cx.509 證書(shū)鏈RFC4945 格式的證書(shū)鏈,對(duì)應(yīng)于用于生成令牌簽名的私鑰。服務(wù)器將使用此信息來(lái)驗(yàn)證簽名是否有效以及令牌是否真實(shí)。x5ux.509 證書(shū)鏈網(wǎng)址服務(wù)器可在其中檢索與用于生成令牌簽名的私鑰對(duì)應(yīng)的證書(shū)鏈的 URL。服務(wù)器將檢索并使用此信息來(lái)驗(yàn)證簽名是否真實(shí)。crit危急服務(wù)器必須理解的標(biāo)頭列表,以便接受令牌為有效令牌

Payload(負(fù)載信息)

也稱為JWT claims,放置需要傳輸?shù)男畔ⅲ腥?lèi):

  • 保留claims:主要包括iss發(fā)行者、exp過(guò)期時(shí)間、sub主題、aud用戶等。

  • 公共claims:定義新創(chuàng)的信息,比如用戶信息和其他重要信息。

  • 私有claims:用于發(fā)布者和消費(fèi)者都同意以私有的方式使用的信息。

以下是Payload的官方定義內(nèi)容:

keyname說(shuō)明iss發(fā)送者標(biāo)識(shí)頒發(fā) JWT 的發(fā)送主體。sub主題標(biāo)識(shí) JWT 的主題。aud接收者標(biāo)識(shí) JWT 所針對(duì)的接收者。每個(gè)在處理 JWT 的主體都必須使用受眾聲明中的值來(lái)標(biāo)識(shí)自己。如果處理的主體在存在此聲明時(shí)未將自己標(biāo)識(shí)為聲明中的值,則必須拒絕 JWT。exp到期時(shí)間標(biāo)識(shí)不得接受 JWT 進(jìn)行處理的過(guò)期時(shí)間。該值必須是日期類(lèi)型,而且是1970-01-01 00:00:00Z 之后的日期秒。nbfjwt的開(kāi)始處理的時(shí)間標(biāo)識(shí) JWT 開(kāi)始接受處理的時(shí)間。該值必須是日期。iatjwt發(fā)出的時(shí)間標(biāo)識(shí) JWT 的發(fā)出的時(shí)間。該值必須是日期。jtijwt id令牌的區(qū)分大小寫(xiě)的唯一標(biāo)識(shí)符,即使在不同的頒發(fā)者之間也是如此。

Payload明文示例:

json復(fù)制代碼{ ??"sub": "12344321", ??"name": "Mars醬", // 私有claims ??"iat": 1516239022 }

經(jīng)過(guò)Base64加密之后的明文,變?yōu)椋?/p>

java復(fù)制代碼eyJzdWIiOiIxMjM0NDMyMSIsIm5hbWUiOiJNYXJz6YWxIiwiaWF0IjoxNTE2MjM5MDIyfQ

也就是第一個(gè).和第二個(gè). 之間的密文串內(nèi)容。

Signatrue(簽名信息)

Signature 部分是對(duì)Header和Payload兩部分的簽名,作用是防止 JWT 被篡改。這個(gè)部分的生成規(guī)則主要是是公式(偽代碼)是:

java復(fù)制代碼Header中定義的簽名算法( ?? ?base64編碼(header) + "." + base64編碼(payload), ?? ?secret )

secret是存放在服務(wù)端加密使用到的鹽。

得到簽名之后,把Header的密文、Payload的密文、Signatrue的密文按順序拼接成為一個(gè)字符串,中間通過(guò).來(lái)連接并分割,整個(gè)串就是JWT了。

JWT實(shí)例

概念講完了,我們來(lái)個(gè)實(shí)例吧,先來(lái)一個(gè)jwt的編碼:

java復(fù)制代碼 ? ?public static String encodeJWT(String key) { ?? ? ? ?// 1. 定義header部分內(nèi)容 ? ? ? ? ?Map headerMap = new HashMap(); ?? ? ? ?headerMap.put("alg", SignatureAlgorithm.HS256.getValue()); ?? ? ? ?headerMap.put("typ", "JWT"); ? ? ? ? ?// 2. 定義payload部分內(nèi)容 ?? ? ? ?Map payloadMap = new HashMap(); ?? ? ? ?payloadMap.put("sub", "mars醬讓你爽一分鐘"); ?? ? ? ?payloadMap.put("iat", UUID.randomUUID()); ?? ? ? ?payloadMap.put("exp", System.currentTimeMillis() + 24 * 60 * 60 * 1000); ?? ? ? ?payloadMap.put("name", "Mars醬"); ?? ? ? ?payloadMap.put("role", "醬油王"); ? ? ? ? ?// 3.生成token ?? ? ? ?String jwtToken = Jwts.builder() ?? ? ? ? ? ? ? ?.setHeaderParams(headerMap) ?? ? ? ? ? ? ? ?.setClaims(payloadMap) ?? ? ? ? ? ? ? ?.signWith(SignatureAlgorithm.HS256, key) ?? ? ? ? ? ? ? ?.compact(); // 拼接header + payload // ? ? ? ?System.out.println(jwtToken); ?? ? ? ?return jwtToken; ?? ?}

我們?cè)趍ain函數(shù)中調(diào)用這個(gè),運(yùn)行得到結(jié)果:

很長(zhǎng)的密文字符串,就不截完整了。其中key是鹽,jsonwebtoken的jar包規(guī)定,key必須字節(jié)數(shù)要大于等于你所用的加密算法的最小字節(jié)數(shù),mars醬這里使用的是HS256,最小的key長(zhǎng)度規(guī)定的就是256:

因此,key值我這里傳入了一個(gè)超長(zhǎng)的key:

java復(fù)制代碼String key = "marsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmarsmars";

如果你的key沒(méi)這么長(zhǎng),你可能會(huì)報(bào)這樣錯(cuò)誤:

下面再來(lái)一個(gè)解密jwt的代碼,入?yún)榧用芎蟮膉wt和鹽key:

java復(fù)制代碼 ? ?public static void decodeJWT(String jwtToken, String key) { ?? ? ? ?try { ?? ? ? ? ? ?Claims claims = Jwts.parser() ?? ? ? ? ? ? ? ? ? ?.setSigningKey(key) ?? ? ? ? ? ? ? ? ? ?.parseClaimsJws(jwtToken) ?? ? ? ? ? ? ? ? ? ?.getBody(); ?? ? ? ? ? ?Object sub = claims.get("sub"); ?? ? ? ? ? ?Object name = claims.get("name"); ?? ? ? ? ? ?Object role = claims.get("role"); ?? ? ? ? ? ?Object exp = claims.get("exp"); ? ? ? ? ? ? ?System.out.println("sub:" + sub + "\nname:" + name.toString() + "\nrole:" + role + "\nexp:" + exp + "\n失效了?" + ((System.currentTimeMillis() - (Long)exp) > 0)); ?? ? ? ?} catch (ExpiredJwtException e) { ?? ? ? ? ? ?System.out.println("mars醬提醒您:token已過(guò)期"); ?? ? ? ?} ?? ?}

在main中調(diào)用后,得到結(jié)果:

把生成的jwt字符串放入官網(wǎng)( jwt.io )的解密界面,和程序解密的結(jié)果一樣,是不是很完美?

優(yōu)缺點(diǎn)

好了,概念說(shuō)完了,實(shí)例也給了,想想jwt有什么優(yōu)缺點(diǎn)?我總結(jié)了一下:

優(yōu)點(diǎn):

  1. 可擴(kuò)展性好 應(yīng)用程序分布式部署的情況下,如果使用session機(jī)制,那就要要做多臺(tái)機(jī)器的數(shù)據(jù)共享,通??梢源嬖跀?shù)據(jù)庫(kù)或者redis里面。而使用jwt不需要共享。

  2. jwt是無(wú)狀態(tài)的 jwt不在服務(wù)端存儲(chǔ)任何狀態(tài)。RESTful API的原則之一是無(wú)狀態(tài),發(fā)出請(qǐng)求時(shí),總會(huì)返回帶有參數(shù)的響應(yīng),不會(huì)產(chǎn)生附加影響。用戶的認(rèn)證狀態(tài)引入這種附加影響,這破壞了這一原則。另外jwt的載荷中可以存儲(chǔ)一些常用信息,用于交換信息,有效地使用 JWT,可以降低服務(wù)器查詢數(shù)據(jù)庫(kù)的次數(shù)。

缺點(diǎn):

  1. 安全性 由于jwt的payload是使用base64編碼的,并沒(méi)有加密,因此jwt中不能存儲(chǔ)敏感數(shù)據(jù)。而session的信息是存在服務(wù)端的,相對(duì)來(lái)說(shuō)更安全。

  2. 一次性 無(wú)狀態(tài)是jwt的特點(diǎn),但也導(dǎo)致了這個(gè)問(wèn)題,jwt是一次性的。想修改里面的內(nèi)容,就必須簽發(fā)一個(gè)新的jwt。

jwt開(kāi)源框架

mars醬這里使用的jwt是io.jsonwebtoken的,它需要在pom中引入依賴:

xml復(fù)制代碼 <!-- jwt api定義 --> ?<dependency> ?<groupId>io.jsonwebtoken</groupId> ?<artifactId>jjwt-api</artifactId> ?<version>0.10.2</version> ?</dependency> ?<!-- jwt api impl實(shí)現(xiàn) --> ?<dependency> ?<groupId>io.jsonwebtoken</groupId> ?<artifactId>jjwt-impl</artifactId> ?<version>0.10.2</version> ?</dependency> ?<!-- jwt json --> ?<dependency> ?<groupId>io.jsonwebtoken</groupId> ?<artifactId>jjwt-jackson</artifactId> ?<version>0.10.2</version> ?</dependency>

其余的jwt框架全在jwt官網(wǎng)列舉了?;靖采w了全語(yǔ)言

好好享受jwt的校驗(yàn)過(guò)程吧

JWT | 一分鐘掌握J(rèn)WT | 概念及實(shí)例的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
合阳县| 罗源县| 维西| 益阳市| 密山市| 邹平县| 濮阳县| 罗源县| 阳东县| 孟州市| 财经| 阳曲县| 荥经县| 南陵县| 宝鸡市| 胶州市| 望都县| 巧家县| 敖汉旗| 台山市| 海宁市| 隆昌县| 栾城县| 林甸县| 怀安县| 安陆市| 扎囊县| 车致| 磐安县| 丰顺县| 阿勒泰市| 丹棱县| 寿宁县| 嘉禾县| 呼图壁县| 霍山县| 石台县| 曲靖市| 宜良县| 齐齐哈尔市| 同江市|