日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

更轻易地实现 Jwt Token

發布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 更轻易地实现 Jwt Token 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

更輕易地實現一個 Jwt Server

Intro

最近在多個項目中都有用到 Jwt Token 認證,就想著把之前項目里 Jwt Token 的使用封裝一下,以便于之后集成起來更加地方便,不用再拷貝代碼了

JWT

JWT 是 JSON Web Token 的縮寫,是目前最流行的基于 Token 的認證解決方案,JWT 是一種無狀態的認證方式,我們不需要依賴 Session,更為簡單,對于隨時準備擴容縮容的云原生應用來說更加的友好。

JWT token 的格式分成三個部分,他們之間以 “.” 作為分隔

  • Header(頭部)

  • Payload(負載)

  • Signature(簽名)

JWT Token

我們可以在 https://jwt.io 網站上查看 token 的內容,也可以自己寫個小工具來查看,token 的內容是 base64 URL 編碼的

JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字符+、/和=,在 URL 里面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL 算法。

JWT Token 內容解析之后如下所示:

Header 是 token 所用到的簽名算法信息,默認是 HMAC SHA 256(HS256) 以及 RSA SHA 256(RS256)

Payload 就是我們 token 中保存的信息,這些信息是可以解析成明文的,所以內容上不能保存敏感信息,只能保存一些敏感度不高的信息

Signature 是基于 header 和 payload 生成出來的,例如使用 HMAC SHA 256 簽名

HMACSHA256(base64UrlEncode(header)?+?"."?+base64UrlEncode(payload),secret)

Sample

介紹了一些基本知識,我們再來看示例吧

首先需要集成 WeihanLi.Web.Extensions 這個 NuGet 包

我們只需要注冊服務即可:

services.AddJwtTokenService(options?=> {options.SecretKey?=?Guid.NewGuid().ToString();options.Issuer?=?"https://id.weihanli.xyz";options.Audience?=?"SparkTodo"; });

SecretKey 是用來生成 token 和 token 簽名校驗的,默認簽名方式 是 HMAC SHA256

Issuer 是簽發人,是指定誰頒發的 token

Audience 是受眾,是指 token 是給誰用的

注冊好服務之后,我們就可以從依賴注入服務中獲取 ITokenService 來進行 token 的操作了

[HttpGet("getToken")] public?async?Task<IActionResult>?GetToken([Required]?string?userName,?[FromServices]?ITokenService?tokenService) {var?token?=?await?tokenService.GenerateToken(new?Claim("name",?userName));return?token.WrapResult().GetRestResult(); }[HttpGet("validateToken")] public?async?Task<IActionResult>?ValidateToken(string?token,?[FromServices]?ITokenService?tokenService) {return?await?tokenService.ValidateToken(token).ContinueWith(r?=>r.Result.WrapResult().GetRestResult()); }

GetToken:

GetToken

VaidateToken:

ValidateToken

Implement

我們來看一些實現細節

public?class?JwtTokenService?:?ITokenService {private?readonly?JwtSecurityTokenHandler?_tokenHandler?=?new();private?readonly?JwtTokenOptions?_tokenOptions;private?readonly?Lazy<TokenValidationParameters>_lazyTokenValidationParameters;public?JwtTokenService(IOptions<JwtTokenOptions>?tokenOptions){_tokenOptions?=?tokenOptions.Value;_lazyTokenValidationParameters?=?new(()?=>_tokenOptions.GetTokenValidationParameters());}public?virtual?Task<TokenEntity>?GenerateToken(params?Claim[]?claims)=>?GenerateTokenInternal(claims);public?virtual?Task<TokenValidationResult>?ValidateToken(string?token){return?_tokenHandler.ValidateTokenAsync(token,?_lazyTokenValidationParameters.Value);}private?async?Task<TokenEntity>?GenerateTokenInternal(bool?refreshToken,?Claim[]?claims){var?now?=?DateTimeOffset.UtcNow;var?claimList?=?new?List<Claim>(){new?(JwtRegisteredClaimNames.Iat,?now.ToUnixTimeMilliseconds().ToString(),?ClaimValueTypes.Integer64)};if?(claims?!=?null){claimList.AddRange(claims);}var?jti?=?claimList.FirstOrDefault(c?=>?c.Type?==?JwtRegisteredClaimNames.Jti)?.Value;if?(jti?is?null){jti?=?_tokenOptions.JtiGenerator?.Invoke()????GuidIdGenerator.Instance.NewId();claimList.Add(new(JwtRegisteredClaimNames.Jti,?jti));}var?jwt?=?new?JwtSecurityToken(issuer:?_tokenOptions.Issuer,audience:?_tokenOptions.Audience,claims:?claimList,notBefore:?now.UtcDateTime,expires:?now.Add(_tokenOptions.ValidFor).UtcDateTime,signingCredentials:?_tokenOptions.SigningCredentials);var?encodedJwt?=?_tokenHandler.WriteToken(jwt);var?response?=?new?TokenEntity(){AccessToken?=?encodedJwt,ExpiresIn?=?(int)_tokenOptions.ValidFor.TotalSeconds};return?response;} }

More

默認是基于 HS256 的簽名方式,你也可以很輕松地切換成使用基于 RSA 的?RS256 方式,可以自己探索一下

更多實現細節可以參考源碼:https://github.com/WeihanLi/WeihanLi.Web.Extensions/tree/dev/src/WeihanLi.Web.Extensions/Authorization/Jwt

下一篇文章我們介紹如何使用 RefreshToken

References

  • https://github.com/WeihanLi/SparkTodo/blob/master/SparkTodo.API/Program.cs#L40

  • https://github.com/WeihanLi/WeihanLi.Web.Extensions/blob/dev/samples/WeihanLi.Web.Extensions.Samples/Program.cs#L40

  • https://github.com/WeihanLi/WeihanLi.Web.Extensions

總結

以上是生活随笔為你收集整理的更轻易地实现 Jwt Token的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。