十、JWT介紹
JWT只是縮寫,全稱則是JSON Web Tokens,是目前流行的跨域認證解決方案,是基於開放標準RFC7519,提供一種身份認證與資訊交換的解決方案,是一種基於JSON的用於在網路上宣告某種主張的令牌(token)。
由於http的連線是狀態的特性,server端和client是不會記住每個請求是誰發過來的,也不會知道當前傳送請求的使用者是否已經對過身份認證,如果使用者的每一個請求,都要與資料庫通訊進行身份認證,會增加server和資料庫的成本。因此,之前的Web應用一般都會用session或 cookie的方式解決。
通俗地說,JWT的本質就是一個字串,它是將使用者資訊儲存到一個Json字串中,然後進行編碼後得到一個JWT token,並且這個JWT token帶有簽名資訊,接收後可以校驗是否被篡改,所以可以用於在各方之間安全地將資訊作為Json物件傳輸。JWT的認證流程如下:
- 使用者第一次登入時,後端核對使用者名稱和密碼,進行身份認證。
2. 身份認證透過後,生成jwt token,並將user的資訊,包括賬號、登入時間等一些不敏感,不重要的資訊記錄在jwt 中的Payload,將其與JWT Header分別進行Base64編碼拼接後簽名,形成一個JWT Token,形成的JWT Token就是一個如同lll.zzz.xxx的字串。
- 後端將jwt token字串作為登入成功的結果返回給client端,client端將返回結果記錄在storage中。
- 使用者再次發起請求時,每次請求都要在請求頭中攜帶這個jwt token,server端在收到這個token之後,進行驗證,驗證透過,從jwt中讀取使用者資訊,並執行後續操作;驗證不能過,返回錯誤資訊。
- 退出登入時刪除儲存的JWT Token即可。
JWT 結構
一個token分為3部分:頭部(header)、載荷(payload)、簽名(signature)
1.頭部(header),JWT頭是一個描述JWT後設資料的JSON物件,alg屬性表示簽名使用的演算法,預設為HMAC SHA256(寫為HS256);typ屬性表示令牌的型別,JWT令牌統一寫為JWT。最後,使用Base64 URL演算法將上述JSON物件轉換為字串儲存
2.載荷(payload),有效載荷部分,是JWT的主體內容部分,是承載訊息具體內容的地方,也是一個JSON物件,包含需要傳遞的資料,需要使用Base64編碼。 JWT指定七個預設欄位供選擇
iss(issuer): jwt簽發者
sub(subject): jwt所面向的使用者
aud(audience): 接收jwt的一方, 受眾
exp(expiration time): jwt的過期時間,這個過期時間必須要大於簽發時間
nbf(Not Before): 生效時間,定義在什麼時間之前.
iat(Issued At): jwt的簽發時間
jti(JWT ID): jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
這些預定義的欄位並不要求強制使用。除以上預設欄位外,我們還可以自定義私有欄位,一般會把包含使用者資訊的資料放到payload中,如下例:
3.簽名(signature),簽名雜湊部分是對上面兩部分資料簽名,需要使用base64編碼後的header和payload資料,透過指定的演算法生成雜湊,以確保資料不會被篡改。首先,需要指定一個金鑰(secret)。該密碼僅僅為儲存在伺服器中,並且不能向使用者公開。然後,使用header中指定的簽名演算法(預設情況下為HMAC SHA256)根據以下公式生成簽名
在計算出簽名雜湊後,JWT頭,有效載荷和簽名雜湊的三個部分組合成一個字串,每個部分用.分隔,就構成整個JWT物件
header和payload可以直接利用base64解碼出原文,從header中獲取雜湊簽名的演算法,從payload中獲取有效資料
signature由於使用了不可逆的加密演算法,無法解碼出原文,它的作用是校驗token有沒有被篡改。服務端獲取header中的加密演算法之後,利用該演算法加上secretKey對header、payload進行加密,比對加密後的資料和客戶端傳送過來的是否一致。
注意:secretKey只能儲存在服務端,而且對於不同的加密演算法其含義有所不同,一般對於MD5型別的摘要加密演算法,secretKey實際上代表的是鹽值
關於jwt更多資訊,可參考jwt.io的說明。
十一、建立JWT服務
- 在Visual Studio 2022的解決方案資源管理器中,使用滑鼠右鍵點選“依賴項”,從彈出選單中選擇“管理NuGet程度包”選單項,或是“工具—》NuGet包管理器器—>管理解決方案的NuGet程式包”選單。如下圖。
2. 在搜尋輸入框中輸入“JWT”,然後安裝JWT程式包,如下圖。
3.在Visual Studio 2022中的NuGet 包管理器控制檯視窗中安裝JWTBearer,由於我這個專案是基於NET6框架的,所以安裝NET6下的最新版本 6.0.11。在PMC中,如下圖。輸入以下命令:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 6.0.11
4. 在Visual Studio 2022中開啟appsettings.json檔案,在此配置檔案中新增JWT的配置,參考程式碼如下,注意SecretKey不能設定成太短的純數字,不然要報錯。
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "ConnectionStrings": { "BookContext": "Server=.;Database=LeaseBooks;Trusted_Connection=True;MultipleActiveResultSets=true" }, "AllowedHosts": "*", "Authentication": { "SecretKey": "Blazor!SecKey@webdemo@vvip.GHTUPAVX", "Issuer": "JWT.Reg22user@Isskl35", "Expires": 10, "Audience": "login.Blazor.audit" } }
Issuer,註冊人
Audience,訪問人
Expires,到期時間