服務端 工作需要又需要用到socketTCP通訊,這麼多年了,終於稍微能寫點了。讓我說其實也說不出個啥來,看了很多的非同步後稍微對非同步socket的導流 endreceive後 再beginreceive 形成一個內迴圈有了個認識,加上我自己的封包拆包機制,然後再仿那些其它的大多數代碼結構弄點onRe ...
學習ASP.NET Core Blazor編程系列文章之目錄 學習ASP.NET Core Blazor編程系列一——綜述 學習ASP.NET Core Blazor編程系列二——第一個Blazor應用程式(上)
學習ASP.NET Core Blazor編程系列三——實體 學習ASP.NET Core Blazor編程系列五——列表頁面 學習ASP.NET Core Blazor編程系列七——新增圖書 學習ASP.NET Core Blazor編程系列八——數據校驗 學習ASP.NET Core Blazor編程系列十三——路由(完) 學習ASP.NET Core Blazor編程系列十五——查詢 學習ASP.NET Core Blazor編程系列十六——排序 學習ASP.NET Core Blazor編程系列二十——文件上傳(完) 學習ASP.NET Core Blazor編程系列二十一——數據刷新 學習ASP.NET Core Blazor編程系列二十二——登錄(1)
十、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@[email protected]", "Issuer": "JWT.Reg22user@Isskl35", "Expires": 10, "Audience": "login.Blazor.audit" } }
SecretKey,密匙
Issuer,註冊人
Audience,訪問人
Expires,到期時間