DRF JWT認證(一)

来源:https://www.cnblogs.com/48xz/archive/2022/04/09/16123916.html
-Advertisement-
Play Games

為什麼要使用JWT認證?構成和原理又是什麼?怎麼還有Base64的事?我都寫了


目錄

DRF JWT認證(一)

image

JWT認證

Json web token (JWT), 是為了在網路應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519).該token被設計為緊湊且安全的,特別適用於分散式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源伺服器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。

Json web token (JWT),token是一種認證機制,用在web開發方向,叫JWT

為什麼使用JWT 認證?

我們想記錄用戶註冊或者登錄後的狀態,或者創建身份認證的憑證,可以使用Session認證機制,或者我們現在所要說的JWT 認證機制,那麼為什麼有了Session認證機制還要使用JWT??

Session機制

image


image

JWT機制

image


image

圖解後,可知如果登錄用戶很多,需要在後端存很多數據,頻繁查詢資料庫,導致效率低,JWT就可以使我們可以不在服務端存數據,又夠保證數據安全,在客戶端存數據 ----> token認證機制

下麵我們瞭解一下JWT的構成和工作原理

構成和工作原理

JWT的構成

JWT由3部分組成:標頭(Header)、有效載荷(Payload)和簽名(Signature)。在傳輸的時候,會將JWT的3部分分別進行Base64編碼後用.進行連接形成最終傳輸的字元串。比如:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

1. header

JWT頭是一個描述JWT元數據的JSON對象,alg屬性表示簽名使用的演算法,預設為HMAC SHA256(寫為HS256);typ屬性表示令牌的類型,JWT令牌統一寫為JWT。最後,使用Base64 URL演算法將上述JSON對象轉換為字元串保存

第一段頭部承載的信息:

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

完整的頭部就像下麵這樣的JSON:

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

然後將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

2. payload

第二段是載荷,載荷就是存放有效信息的地方,是JWT的主體內容部分,也是一個JSON對象,承載的信息:

  • 標準中註冊的聲明
  • 公共的聲明
  • 私有的聲明

標準中註冊的聲明 (建議但不強制使用) :

  • iss: jwt簽發者
  • sub: jwt所面向的用戶
  • aud: 接收jwt的一方
  • exp: jwt的過期時間,這個過期時間必須要大於簽發時間
  • nbf: 定義在什麼時間之前,該jwt都是不可用的.
  • iat: jwt的簽發時間
  • jti: jwt的唯一身份標識,主要用來作為一次性token,從而迴避時序攻擊。

公共的聲明 : 公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息,但不建議添加敏感信息,因為該部分在客戶端可解密.

私有的聲明 : 私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。

除以上標準註冊聲明欄位外,我們還可以自定義欄位,一般會把包含用戶信息的數據放到payload中,如下例:

{
  "sub": "1234567890",
  "name": "HammerZe",
  "admin": true
}

註意:雖然說用戶信息數據可以存放到payload中,但是預設情況下JWT是未加密的,Base64演算法也只是編碼並不會提供安全的加密演算法,一般程式員拿到Base64編碼的字元串都可以解碼出內容,所以不要存隱私信息,比如密碼,防止泄露,存一些非敏感信息

3. signature

簽名哈希部分是對上面兩部分數據簽名,需要使用base64編碼後的header和payload數據,通過指定的演算法生成哈希,以確保數據不會被篡改。首先,需要指定一個密鑰(secret)。該密碼僅僅為保存在伺服器中,並且不能向用戶公開。然後,使用header中指定的簽名演算法(預設情況下為HMAC SHA256)根據以下公式生成簽名

HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

簡單的說第三段是簽證信息,這個簽證信息由三部分組成:

  • header (base64後的)
  • payload (base64後的)
  • secret

這個部分需要base64加密後的header和base64加密後的payload使用.連接組成的字元串,然後通過header中聲明的加密方式進行加鹽secret組合加密,然後就構成了JWT的第三部分。

註意:secret是保存在伺服器端的,jwt的簽發生成也是在伺服器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了。

關於簽發和核驗JWT,我們可以使用Django REST framework JWT擴展來完成。

總結

註意JWT每部分的作用,在服務端接收到客戶端發送過來的JWT token之後:

header和payload可以直接利用base64解碼出原文,從header中獲取哈希簽名的演算法,從payload中獲取有效數據

signature由於使用了不可逆的加密演算法,無法解碼出原文,它的作用是校驗token有沒有被篡改。服務端獲取header中的加密演算法之後,利用該演算法加上secretKey對header、payload進行加密,比對加密後的數據和客戶端發送過來的是否一致。註意secretKey只能保存在服務端,而且對於不同的加密演算法其含義有所不同,一般對於MD5類型的摘要加密演算法,secretKey實際上代表的是鹽值

本質原理

JWT認證演算法:簽發與校驗

"""
1)jwt分三段式:頭.體.簽名 (head.payload.sgin)
2)頭和體是可逆加密,讓伺服器可以反解出user對象;簽名是不可逆加密,保證整個token的安全性的
3)頭體簽名三部分,都是採用json格式的字元串,進行加密,可逆加密一般採用base64演算法,不可逆加密一般採用hash(md5)演算法
4)頭中的內容是基本信息:公司信息、項目組信息、token採用的加密方式信息
{
	"company": "公司信息",
	...
}
5)體中的內容是關鍵信息:用戶主鍵、用戶名、簽發時客戶端信息(設備號、地址)、過期時間
{
	"user_id": 1,
	...
}
6)簽名中的內容時安全信息:頭的加密結果 + 體的加密結果 + 伺服器不對外公開的安全碼 進行md5加密
{
	"head": "頭的加密字元串",
	"payload": "體的加密字元串",
	"secret_key": "安全碼"
}
"""

簽發:根據登錄請求提交來的 賬號 + 密碼 + 設備信息 簽發 token

"""
1)用基本信息存儲json字典,採用base64演算法加密得到 頭字元串
2)用關鍵信息存儲json字典,採用base64演算法加密得到 體字元串
3)用頭、體加密字元串再加安全碼信息存儲json字典,採用hash md5演算法加密得到 簽名字元串

賬號密碼就能根據User表得到user對象,形成的三段字元串用 . 拼接成token返回給前臺
"""

校驗:根據客戶端帶token的請求 反解出 user 對象

"""
1)將token按 . 拆分為三段字元串,第一段 頭加密字元串 一般不需要做任何處理
2)第二段 體加密字元串,要反解出用戶主鍵,通過主鍵從User表中就能得到登錄用戶,過期時間和設備信息都是安全信息,確保token沒過期,且時同一設備來的
3)再用 第一段 + 第二段 + 伺服器安全碼 不可逆md5加密,與第三段 簽名字元串 進行碰撞校驗,通過後才能代表第二段校驗得到的user對象就是合法的登錄用戶
"""

JWT的種類

其實JWT(JSON Web Token)指的是一種規範,這種規範允許我們使用JWT在兩個組織之間傳遞安全可靠的信息,JWT的具體實現可以分為以下幾種:

  • nonsecure JWT:未經過簽名,不安全的JWT
  • JWS:經過簽名的JWT
  • JWEpayload部分經過加密的JWT

nonsecure JWT

未經過簽名,不安全的JWT。其header部分沒有指定簽名演算法

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

並且也沒有Signature部分

JWS

JWS ,也就是JWT Signature,其結構就是在之前nonsecure JWT的基礎上,在頭部聲明簽名演算法,併在最後添加上簽名。創建簽名,是保證jwt不能被他人隨意篡改。我們通常使用的JWT一般都是JWS

為了完成簽名,除了用到header信息和payload信息外,還需要演算法的密鑰,也就是secretKey。加密的演算法一般有2類:

  • 對稱加密:secretKey指加密密鑰,可以生成簽名與驗簽
  • 非對稱加密:secretKey指私鑰,只用來生成簽名,不能用來驗簽(驗簽用的是公鑰)

JWT的密鑰或者密鑰對,一般統一稱為JSON Web Key,也就是JWK

到目前為止,jwt的簽名演算法有三種:

  • HMAC【哈希消息驗證碼(對稱)】:HS256/HS384/HS512
  • RSASSA【RSA簽名演算法(非對稱)】(RS256/RS384/RS512)
  • ECDSA【橢圓曲線數據簽名演算法(非對稱)】(ES256/ES384/ES512)

base64編碼與解碼

import base64
import json

dic_info={
  "sub": "1234567890",
  "name": "HammerZe",
  "admin": True
}

'''base64編碼'''
# 必須是bytes類型
s = json.dumps(dic_info).encode('utf8')
enbase64_str = base64.b64encode(s)
print(enbase64_str)
# b'eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9'

'''base64解碼'''
en_res = b'eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogImxxeiIsICJhZG1pbiI6IHRydWV9'

debase64_str = base64.b64decode(en_res).decode('utf8')
print(base64.b64decode(en_res),type(base64.b64decode(en_res)))
# b'{"sub": "1234567890", "name": "HammerZe", "admin": true}' <class 'bytes'>
print(debase64_str)
# {"sub": "1234567890", "name": "HammerZe", "admin": true}

註意

  • base64長度必須是4的倍速,如果不夠就使用=補齊,

哪些情景需求base64?建議參考下博文

為什麼要使用base64編碼,有哪些情景需求? - 知乎 (zhihu.com)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、基礎使用 1、變數、表達式、class style、子元素和組件 2、if else、三元表達式、邏輯運算符 && || 3、map、key 4、bind this 5、關於event參數,react的event不是原生的,event.nativeEvent才是指向原生event,所有的事件都是 ...
  • 1. 今天的內容其實挺多的,我們慢慢來說。首先第一個是xhr的基本使用,什麼是xhr? XMLHTTPRequest是瀏覽器提供的js對象,可以請求伺服器上的數據資源,包括我們前面一直用的jq裡面的三個請求資源的方法都是基於xhr來封裝的。 那麼首先我們看到xhr的get請求怎麼來實現 首先要創建x ...
  • 1. 今天繼續ajax的一個學習,首先明確一個觀念,介面,什麼是介面,當使用ajax請求數據時,被請求的url就叫做數據介面也就是介面,註意每個介面必須有請求方式,這裡有一個介面的測試工具,postman自稱是全球最快的,反正使用起來沒多大毛病,使用這個軟體的時候有一個註意點就是在post請求的時候 ...
  • 進入ajax了,想要進入vue還有一個前提就是要把ajax給熟悉一下,看一看客戶端與伺服器之間是怎麼一個通信的過程,第一天主要是先瞭解了一下ajax的一些介紹,ajax嘛,在進入之前,肯定是要瞭解一下客戶端與伺服器之間的一個通信過程,其實不管是請求還是發送都遵循的一個原則,即請求、處理、響應,如何來 ...
  • 一、前言 雖說上學期為了助眠看了一點 Java 但是散而不精,看而不敲,所以這學期正式學 Java 並沒有想想中那麼容易... 直觀感受:Java有很多和C/C不一樣的地方,Java太嚴謹了,但是相比C/C來說也更安全(不需要領著指針亂跑).... 前三次PTA題目集的小總結 總體來看,前兩次的題目 ...
  • 不斷踩坑並解決問題是每個程式員進階到資深的必要經歷並以此獲得滿足感,而不斷閱讀開源項目源碼和總結思想是每個架構師成長最佳途徑。本篇拉開SpringCloud Alibaba最新版本實戰和原理序幕,以工程實踐的簡單完整實戰示例為主線,步步深入並可為實際項目中帶來啟發 ...
  • 上個月線上生產環境有幾個介面出現異常響應,查看生產日誌後發現,如下錯誤 線上Redis客戶端使用的是SpringBoot預設的Lettuce客戶端,並且沒有指定連接池,connection reset by peer這個錯誤是當前客戶端連接在不知情的情況下被服務端斷開後產生,也就是說當前客戶端Red ...
  • Spring 簡介 spring,英文單詞為春天,表示為軟體行業帶來了春天。 2002年,首次推出了Spring框架的雛形:interface21框架。官網為:www.interface21.io但是現在進去時間略長。 Spring框架是以上面這個框架為基礎重新設計,並不斷對其進行改進豐富其內涵,在 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...