關於JWT 的那些事兒

2021-10-23 18:01:09 字數 3041 閱讀 9250

jwt 英文名是 json web token,是一種用於通訊雙方之間傳遞安全資訊的簡潔的、url安全的表述性宣告規範,經常用於跨域身份驗證。

jwt 以 json 物件的形式安全地傳遞資訊。因為存在數字簽名,因此所傳遞的資訊是安全的。

在了解 jwt 之前我們先來看一下為什麼需要 jwt

傳統方式的侷限性

傳統的登入方式:使用者端輸入使用者名稱密碼,伺服器端校驗通過,根據使用者資訊生成乙個 token,將 token 和 user_id 存到資料庫或 session會話 中,並將 token 返回給前端,存入cookie,瀏覽器每次請求都會帶上 cookie,服務端根據cookie中的 token 查詢使用者(如user_id),驗證使用者有效性。

傳統方式存在以下弊端:

① 如果出現xss(跨站指令碼攻擊)漏洞,由於 cookie 可以被 js 讀取,xss 漏洞會導致使用者 token 被洩露。解決方案:

② 將驗證資訊存到資料庫中,每次驗證的時候,都需要去資料庫中查詢,增加了資料庫的查詢和儲存開銷。

③ 如果將 token 存到 session 中,也會增加伺服器的儲存壓力。

④ 無法橫向擴充套件。在伺服器集群或者面向服務且跨域的結構中,需要資料庫來儲存 session 會話,實現多個伺服器之間的會話資料共享。在單點登入中為了解決共享 session 問題,其中一種方法是持久化 session 資料,但是缺點也非常明顯,就是架構修改很困難,驗證邏輯需要重寫,並且整體依賴於資料庫,如果儲存 session 會話的資料庫掛掉那麼整個身份認證就無法使用,進而導致系統無法登入。

jwt的優勢

① 可以通過 url post 引數或者 http header 中傳送,資料量小,傳輸速度快。

② 自包含:負載中包含了使用者所需要的所有資訊,避免多次查詢資料庫。原來是先拿著 token 去找 user_id,現在是,jwt 的有效載荷中就包含了 user_id 等資訊。這樣就不需要伺服器端儲存 session 資訊。

說白了 jwt 就是一段資料,我理解的是它既代表了一種思想,又提供了具體的解決方案

jwt 是由三段字串和兩個 . 組成,類似於這樣:******.yyyyyy.zzzzzz,每個字串代表了不同的功能。

jwt 頭 header

jwt 頭描述了 jwt 元資料,是乙個 json 物件,它的格式如下:

json
其中 「alg」 屬性表示簽名所使用的演算法,jwt 簽名預設的演算法為 hmac sha256 ,

「typ」 屬性表示令牌型別,這裡就是 jwt。

有效載荷payload

有效載荷是 jwt 的主體,也是個 json 物件。有效載荷包含三個部分:

下面這個**段就是定義了乙個有效載荷:

json
雜湊簽名 signature

雜湊簽名的演算法主要是確保資料不會被篡改。它主要是對前面所講的兩個部分進行編碼,通過 jwt 頭定義的演算法(「alg」:「hs256」)生成雜湊。

③signature = hmacsha256(

base64urlencode(①header) +

"." +

base64urlencode(②payload),

password

)

最終

jwt = header.payload.signature
① client 通過賬號密碼登入,server 驗證通過後,將使用者的 id 及其他非敏感資訊作為jwt payload,將其與頭部分別進行 base64 編碼後簽名,生成 jwt,然後將 jwt返 回給 client。

② client 將收到的 jwt 儲存到 localstorage 或者 sessionstorage 中,跳轉到登入頁或請求 api,將 jwt 傳送給 server;退出登入時,client 刪除儲存的 jwt 資訊即可。

③ server端進行過濾器攔截請求(驗證jwt的有效性),若通過,則進行業務邏輯操作並想客戶端返回資料,若不通過,則返回錯誤資訊, client 提示錯誤,跳轉回登入頁面。

服務端驗證 jwt 的過程就是簽名的過程,如何判判斷客戶端傳送的 jwt 就是我剛才給你的那個?關鍵就在於儲存在服務端的密碼

jwt 最終是由 header、payload、signature 三部分組成,其中簽名又是由 header 和 payload 的編碼以及密碼組成,當客戶端傳送 jwt 過來,服務端將 header 和 payload 以及儲存在服務端的密碼(一般是加密過的,而不是明文)重新進行簽名,然後將此簽名與客戶端傳送的 jwt 中的簽名進行比對,如果相同則認為客戶端傳送過來的這個 jwt 就是我剛才給你傳送的那個,從而驗證客戶端身份。

這裡的關鍵就在於儲存在服務端的密碼,因為密碼只有服務端有,因此就保證了簽名的唯一性。而從客戶端傳送過來的 jwt 中是無法得到的密碼的,因為密碼通過雜湊被包含在了簽名中,而雜湊是不可逆的,這就避免了jwt 在傳輸過程中的密碼洩漏問題。

jwt 通常用來設計使用者認證和授權系統,還有我們通常說的單點登入等。

在使用 jwt 時需要注意以下事項:

jwt 預設不加密,如果要寫入敏感資訊必須加密,可以用生成的原始令牌再次對內容進行加密;

jwt只適合向 web 端傳遞一些非敏感資訊,因為 base64 編碼是可逆的,很容易被破解;

jwt 無法使伺服器儲存會話狀態,當令牌生成後在有效期內無法取消也不能更改;

jwt 包含認證資訊,如果洩露了,任何人都可以獲得令牌所有的許可權;因此 jwt 有效期不能太長,對於重要操作每次請求都必須進行身份驗證。

jwt本質只能是能夠避免了服務端進行儲存token的弊端,服務端通過採用數字簽名的方式避免只進行驗證而不儲存,但是jwt本身的明文傳輸仍然是不安全,jwt可以在ssl的安全通道下進行傳輸。jwt最大的作用也是認證。

關於Python那些事兒

1.易於學習 python有相對較少的關鍵字,結構簡單,和乙個明確定義的語法,學習起來更加簡單。2.易於閱讀 python 定義的更清晰。3.易於維護 python的成功在於它的源 是相當容易維護的。4.乙個廣泛的標準庫 python的最大的優勢之一是豐富的庫,跨平台的,在unix,windows和...

關於Nginx那些事兒

記憶體少 併發能力強,效能優化 正向 在瀏覽器中配置 伺服器,實現客戶端對伺服器的訪問。也就是說,在一般情況下,我們客戶端無法直接訪問到伺服器,需要有那麼乙個中臺作為中間應用實現訪問。反向 反向 中,客戶端是無知的,不知道是否配置了伺服器,我們將資料發到反向 伺服器上去,反向 伺服器選擇目標伺服器獲...

關於BOM的那些事兒

window物件 1.window物件是最頂層的物件 2.window物件有六大屬性,這六大屬性本身也是物件 3.window物件旗下的document也是物件 並且document旗下有五大屬性 4.document旗下的五大屬性又是物件,總結 都是物件 window screenleft 和 s...