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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

jwt token注销_辩证的眼光搞懂 JWT 这个知识点

發布時間:2024/1/23 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jwt token注销_辩证的眼光搞懂 JWT 这个知识点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是 JWT

概念

JSON Web Token(簡稱 JWT)是目前最流行的跨域認證解決方案。

JWT 原理

JWT 組成

JWT 由三部分組成:Header,Payload,Signature 三個部分組成,并且最后由.拼接而成。

Header

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

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

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

最后將上面的 JSON 對象使用 Base64URL 算法轉成字符串。

Payload

Payload 中由 Registered Claim 以及需要通信的數據組成。它也是 JSON 格式,另外這些數據字段也叫 Claim。JWT 規定了7個官方字段如下

iss (issuer):簽發人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):受眾
nbf (Not Before):生效時間
iat (Issued At):簽發時間
jti (JWT ID):編號

除了官方的字段外你也可以自定義一些字段,比如 user_id,name 等

Registered Claim 中比較重要的是 "exp" Claim 表示過期時間,在用戶登錄時會設置過期時間,用于后面過期校驗。

const payload = {
// 表示 jwt 創建時間
iat: 1532135735,

// 表示 jwt 過期時間
exp: 1532136735,

// 用戶 id,用以通信
user_id: 123456
}

Signature

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

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

// 由 HMACSHA256 算法進行簽名,secret 不能外泄
const sign = HMACSHA256(base64.encode(header) + '.' + base64.encode(payload), secret)

// jwt 由三部分拼接而成
const jwt = base64.encode(header) + '.' + base64.encode(payload) + '.' + sign

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

JWT 校驗原理

圖片總是更清晰:

通過前面講解的 jwt 生成規則,jwt 前兩部分是對 header 以及 payload 的 base64 編碼。?當服務器收到客戶端的 token 后,解析前兩部分得到 header 以及 payload,并使用 header 中的算法與 服務端本地私有 secret 進行簽名,判斷與 jwt 中攜帶的簽名是否一致。

編碼擴展知識

  • base64

    由于 ASCII 碼成為了國際標準,所以我們要把其它字符轉成 ASCII 就要用到 base64。

    utf-8 -> base64(編碼) -> ASCII

    ASCII -> base64(解碼) -> utf-8

    這樣就可以讓只支持 ASCII 的計算機支持 utf-8 了。

    base64 幾個特點 :2進制的;要比源數據多33%;常用于郵件;?= 號的個數是由 /3 的余數來決定的,最多能有 2 個 = 號;

    主要用于初步的加密(非明文可見)和安全的網絡傳輸。

  • UrlEncode

    例子:www.baidu.com?a=nihao

    上面的例子可以看出 a 的值是你好

    如果要把 a 的值換成 “=” 字符呢?這樣嗎:www.baidu.com?a== ,肯定不行啦,“=” 是特殊字符

    所以把 “=” UrlEncode后 “%3d”

    www.baidu.com?a=%3d

    服務器拿到 a 解碼得到 “=”

    所以說 url 是限制性編碼

看完這兩個編碼應該明白為什么上面base64.encode這種格式轉換。JWT ?作為一個令牌(token),有些場合可能會放到 URL(比如 www.inode.club/?token=xxx)

JWT 與 Session 對比

有無狀態對比

  • Session

    Session 是一種記錄服務器和客戶端會話狀態的機制,需要在數據庫或者 Redis 中保存用戶信息和token信息,所以它是有狀態的。

  • JWT 看完了前面的 JWT 結構和 JWT 校驗原理,在后端并不需要存儲數據,直接通過私有密鑰驗證就可以了。

當有這樣的一個需求,一家公司下同時關聯了多個業務,A業務網站,B業務網站,但是現在要求用戶在A網站登陸過,再訪問B網站的時候能夠自動登陸,JWT 就可以很快的實現這個需求,把 JWT 直接存儲在前端,后端只要校驗 JWT 就可以了。

注:這個需求用 session 也是可以實現的,只是會存儲狀態,查詢存儲,沒有 JWT 方便而已。

適用場景對比

郵箱驗證

很多網站在注冊成功后添加了郵箱驗證功能,功能實現:用戶注冊成功后,完善郵箱,服務端會給用戶郵箱發一個鏈接,用戶點開鏈接校驗成功,這個功能使用 JWT 是個不錯的選擇。

// 把郵箱以及用戶id綁定在一起,設置生效時間
const code = jwt.sign({ email, userId }, secret, { expiresIn: 60 * 30 })

// 在此鏈接校驗驗證碼
const link = `https://www.inode.club/code=${code}`

做那些短期的驗證需求(強烈推薦的場景)

比如在?BFF?層,用 JWT 去驗證傳遞一些數據還是不錯的選擇,可以把有效時間設置的短一些,過期了就需要重新去請求,我這么直接表述你可能還不太懂,舉個現實生活中的例子。

我們上學的時候,有班主任學科老師這兩個概念,有一天你想請假,你需要先去找班主任開一個請假條,然后拿去給你的班主任簽完字之后,你會將請假條交給你的學科課教師,學科教師確認簽字無誤后,把請假條收了,并在請假記錄表中作出了相應記錄。

上面的例子中,“請假申請單”就是JWT中的payload,領導簽字就是base64后的數字簽名,領導是issuer,“學科教師的老王”即為JWT的audience,audience需要驗證班主任簽名是否合法,驗證合法后根據payload中請求的資源給予相應的權限,同時將JWT收回。

放到一些系統集成的應用場景中,例如我前面說的?BFF?中其實 JWT 更適合一次性操作的認證:

服務 B 你好, 服務 A 告訴我,我可以操作 , 這是我的憑證(即 JWT )

在這里,服務 A 負責認證用戶身份(類似于上例班主任批準請假),并頒布一個很短過期時間的JWT給瀏覽器(相當于上例的請假單),瀏覽器(相當于上例請假的我們)在向服務 B 的請求中帶上該 JWT,則服務 B(相當于上例的任課教師)可以通過驗證該 JWT 來判斷用戶是否有權限執行該操作。通過這樣,服務 B 就成為一個安全的無狀態的服務。

個人還是認為 JWT 更適合做一些一次性的安全認證,好多其他場景考慮多了之后又做回了 session,傳統的 cookie-session 機制工作得更好,但是對于一次性的安全認證,頒發一個有效期極短的JWT,即使暴露了危險也很小。上面的郵箱驗證其實也是一次性的安全認證。

跨域認證

因為 JWT 并不使用 Cookie ,所以你可以使用任何域名提供你的 API 服務而不需要擔心跨域資源共享問題(CORS)。JWT 確實是跨域認證的一個解決方案,但是對于跨域場景時要注意一點。?客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。

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

Authorization: Bearer另一種做法是,跨域的時候,JWT 就放在 POST 請求的數據體里面。

跨域知識擴展

跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。為了應付面試,我們每次都隨便背幾個方案。但是如果突然問你為什么會有跨域這個問題出現??...停頓幾秒,這里只是普及一下,知道的可以忽略掉。

推薦一篇很棒的跨域文章:https://segmentfault.com/a/1190000015597029

登陸驗證

登陸驗證:不需要控制登錄設備數量以及注銷登陸情況,無狀態的 jwt 是一個不錯的選擇。具體實現流程,可以看上文中的校驗原理,校驗原理使用的登陸驗證例子。

當需求中出現控制登陸設備數量,或者可以注銷掉用戶時,可以考慮使用原有的 session 模式,因為針對這種登陸需求,需要進行的狀態存儲對 jwt 添加額外的狀態支持,增加了認證的復雜度,此時選用 session 是一個不錯的選擇。?針對上面的特殊需求,可能也有小伙伴仍喜歡使用 jwt ,補充一下特殊案例

注銷登陸

用戶注銷時候要考慮 token 的過期時間。

  • session: 只需要把 user_id 對應的 token 清掉即可 ;
  • jwt: 使用 redis,需要維護一張黑名單,用戶注銷時把該 token 加入黑名單,過期時間與 jwt 的過期時間保持一致。
用戶登陸設備控制
  • session: 使用 sql 類數據庫,維護一個用戶驗證token表,每次登陸重置表中 token 字段,每次請求需要權限接口時,根據 token 查找 user_id(也可以使用 redis 維護 token 數據的存儲)

  • jwt: 假使使用 sql 類數據庫,維護一個用戶驗證token表,表中添加 token 字段,每次登陸重置 token 字段,每次請求需要權限接口時,根據 jwt 獲取 user_id,根據 user_id 查用戶表獲取 token 判斷 token 是否一致。(也可以使用 redis 維護 token 數據的存儲)

適合做那些事來講的,其實也就是針對JWT的優勢來說的,還有一些辯證性的理解。接下來說說 JWT 的缺點。

JWT 注意事項(缺點)

  • 更多的空間占用。如果將原存在服務端session中的信息都放在JWT中保存,會造成JWT占用的空間變大,需要考慮客戶端cookie的空間限制等因素,如果放在Local Storage,則可能會受到 XSS 攻擊。
  • 無法作廢已頒布的令牌。JWT 使用時由于服務器不需要存儲 Session 狀態,因此使用過程中無法廢棄某個 Token 或者更改 Token 的權限。也就是說一旦 JWT 簽發了,到期之前就會始終有效,除非服務器部署額外的邏輯。
  • 用戶信息安全。通過J WT 的組成結構可以看出,Payload 存儲的一些用戶信息,它是通過Base64加密的,可以直接解密,不能將秘密數據寫入 JWT,如果使用需要對 JWT 進行二次加密。
  • 缺點與優勢都知道了,我想怎么選就看你自己了。

    總結

    本文對 JWT 進行的一個辯證的講解,優勢和缺點,以及個人認為合適的適用場景,JWT 并不是銀彈,是否采用 JWT,一定要多考慮一下業務場景。希望本文讓小伙伴們對 JWT 認識的更好些。

    ?? 看完三件事

    大家好,我是koala,如果你覺得這篇內容對你挺有啟發,我想邀請你幫我三個小忙:

    • 點個【在看】,或者分享轉發,讓更多的人也能看到這篇內容

    • 關注公眾號【程序員成長指北】,不定期分享原創&精品技術文章。

    • 添加微信【?coder_qi?】。加入程序員成長指北公眾號交流群。

    “在看轉發”是最大的支持

    總結

    以上是生活随笔為你收集整理的jwt token注销_辩证的眼光搞懂 JWT 这个知识点的全部內容,希望文章能夠幫你解決所遇到的問題。

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