jwt token登出 搞懂 JWT 這個知識點

2021-10-13 21:59:39 字數 4369 閱讀 6927

json web token(簡稱 jwt)是目前最流行的跨域認證解決方案。

jwt 由三部分組成:header,payload,signature 三個部分組成,並且最後由.拼接而成。

header 部分是乙個 json 物件,描述 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 = 

signature

signature 部分是對前兩部分的簽名,防止資料篡改。

首先,需要指定乙個金鑰(secret)。這個金鑰只有伺服器才知道,不能洩露給使用者。然後,使用 header 裡面指定的簽名演算法(預設是 hmac sha256),按照下面的公式產生簽名。

// 由 hmacsha256 演算法進行簽名,secret 不能外洩

const sign = hmacsha256(base64.encode(header) + '.' + base64.encode(payload), secret)

// jwt 由三部分拼接而成

算出簽名以後,把 header、payload、signature 三個部分拼成乙個字串,每個部分之間用""(.)分隔,。

總是更清晰:

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

當有這樣的乙個需求,一家公司下同時關聯了多個業務,a業務**,b業務**,但是現在要求使用者在a**登陸過,再訪問b**的時候能夠自動登陸,jwt 就可以很快的實現這個需求,把 jwt 直接儲存在前端,後端只要校驗 jwt 就可以了。

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

郵箱驗證

// 把郵箱以及使用者id繫結在一起,設定生效時間

const code = jwt.sign(, secret, )

// 在此鏈結校驗驗證碼

const link = `

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

比如在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 請求的資料體裡面。

跨域知識擴充套件

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

登陸驗證

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

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

登出登陸

使用者登出時候要考慮 token 的過期時間。

使用者登陸裝置控制

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

更多的空間占用。如果將原存在服務端session中的資訊都放在jwt中儲存,會造成jwt占用的空間變大,需要考慮客戶端cookie的空間限制等因素,如果放在local storage,則可能會受到 xss 攻擊。

無法作廢已頒布的令牌。jwt 使用時由於伺服器不需要儲存 session 狀態,因此使用過程中無法廢棄某個 token 或者更改 token 的許可權。也就是說一旦 jwt 簽發了,到期之前就會始終有效,除非伺服器部署額外的邏輯。

使用者資訊保安。通過j wt 的組成結構可以看出,payload 儲存的一些使用者資訊,它是通過base64加密的,可以直接解密,不能將秘密資料寫入 jwt,如果使用需要對 jwt 進行二次加密。

缺點與優勢都知道了,我想怎麼選就看你自己了。

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

thinkphp框架使用JWTtoken的方法詳解

簡介 一 jwt介紹 全稱json web token,基於json的開放標準 rfc 7519 以token的方式代替傳統的cookie session模式,用於各伺服器 客戶端傳遞資訊簽名驗證。二 jwt優點 1 服務端不需要儲存傳統會話資訊,沒有跨域傳輸問題,減小伺服器開銷。2 jwt構成簡單...

jwt token自動重新整理的問題

在restframework使用jwt時,遇到了兩個引數jwt expiration delta和jwt refresh expiration delta jwt expiration delta datetime.timedelta minutes 30 jwt allow refresh tru...

JWT token過期自動續期解決方案

jwt jwt全稱json web token,由三部分組成header 頭部,用於描述關於該jwt的最基本的資訊,例如其型別以及簽名所用的演算法等 payload 載荷,就是存放有效資訊的地方,在這一部分中存放過期時間 和signature 簽證,簽證資訊 token token就是後端生成的jw...