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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

使用identity+jwt保护你的webapi(二)——获取jwt token

發布時間:2023/12/4 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用identity+jwt保护你的webapi(二)——获取jwt token 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

上一篇已經介紹了identity在web api中的基本配置,本篇來完成用戶的注冊,登錄,獲取jwt token。

開始

開始之前先配置一下jwt相關服務。

配置JWT

首先NuGet安裝包:

<PackageReference?Include="Microsoft.AspNetCore.Authentication.JwtBearer"?Version="5.0.10"?/>

appsettings.json中添加jwt配置:

"JwtSettings":?{"SecurityKey":?"qP1yR9qH2xS0vW2lA3gI4nF0zA7fA3hB","ExpiresIn":?"00:10:00" }

為了方便,新建一個配置類JwtSettings:

public?class?JwtSettings {public?string?SecurityKey?{?get;?set;?}public?TimeSpan?ExpiresIn?{?get;?set;?} }

在Startup中配置jwt:

public?void?ConfigureServices(IServiceCollection?services) {//省略......var?jwtSettings?=?Configuration.GetSection(nameof(JwtSettings)).Get<JwtSettings>();services.AddSingleton(jwtSettings);var?tokenValidationParameters?=?new?TokenValidationParameters{ValidateIssuer?=?false,ValidateAudience?=?false,ValidateIssuerSigningKey?=?true,IssuerSigningKey?=?new?SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtSettings.SecurityKey)),ClockSkew?=?TimeSpan.Zero,};services.AddAuthentication(options?=>{options.DefaultAuthenticateScheme?=?JwtBearerDefaults.AuthenticationScheme;options.DefaultScheme?=?JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme?=?JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options?=>?{?options.TokenValidationParameters?=?tokenValidationParameters;?}); }

最后別忘了UseAuthentication:

app.UseAuthentication();?//?add app.UseAuthorization();

結構搭建

下面把項目基本結構搭建好,做好接口,后面實現:

以下是各個類的定義:

//?用戶注冊請求參數 public?class?RegisterRequest {public?string?UserName?{?get;?set;?}public?string?Password?{?get;?set;?}public?string?Address?{?get;?set;?} }//?用戶登錄請求參數 public?class?LoginRequest {public?string?UserName?{?get;?set;?}public?string?Password?{?get;?set;?} }//?注冊?登錄?成功后返回?token public?class?TokenResponse {[JsonPropertyName("access_token")]?public?string?AccessToken?{?get;?set;?}[JsonPropertyName("token_type")]?public?string?TokenType?{?get;?set;?} }//?登錄?注冊?失敗時返回錯誤信息 public?class?FailedResponse {public?IEnumerable<string>?Errors?{?get;?set;?} }//?IUserService?接口 public?interface?IUserService {Task<TokenResult>?RegisterAsync(string?username,?string?password,?string?address);Task<TokenResult>?LoginAsync(string?username,?string?password); }//?UserService?實現 public?class?UserService?:?IUserService {public?Task<TokenResult>?RegisterAsync(string?username,?string?password,?string?address){throw?new?System.NotImplementedException();}public?Task<TokenResult>?LoginAsync(string?username,?string?password){throw?new?System.NotImplementedException();} }//?TokenResult?定義 public?class?TokenResult {public?bool?Success?=>?Errors?==?null?||?!Errors.Any();public?IEnumerable<string>?Errors?{?get;?set;?}public?string?AccessToken?{?get;?set;?}public?string?TokenType?{?get;?set;?} }

最后是UserController:

[Route("api/[controller]")] [ApiController] public?class?UserController?:?ControllerBase {private?readonly?IUserService?_userService;public?UserController(IUserService?userService){_userService?=?userService;}[HttpPost("Register")]public?async?Task<IActionResult>?Register(RegisterRequest?request){var?result?=?await?_userService.RegisterAsync(request.UserName,?request.Password,?request.Address);if?(!result.Success){return?BadRequest(new?FailedResponse(){Errors?=?result.Errors});}return?Ok(new?TokenResponse{AccessToken?=?result.AccessToken,TokenType?=?result.TokenType});}[HttpPost("Login")]public?async?Task<IActionResult>?Login(LoginRequest?request){var?result?=?await?_userService.LoginAsync(request.UserName,?request.Password);if?(!result.Success){return?Unauthorized(new?FailedResponse(){Errors?=?result.Errors});}return?Ok(new?TokenResponse{AccessToken?=?result.AccessToken,TokenType?=?result.TokenType});} }

service實現

上面已經做好了基本的結構,接下來就是實現UserService中的RegisterAsync和LoginAsync方法了。這里主要用到identity中的UserManager,UserManager封裝了很多用戶操作的現成方法。

在UserService中先做一個私有方法,根據user創建jwt token;用戶注冊,登錄成功后調用此方法得到token返回即可:

private?TokenResult?GenerateJwtToken(AppUser?user) {var?key?=?Encoding.ASCII.GetBytes(_jwtSettings.SecurityKey);var?tokenDescriptor?=?new?SecurityTokenDescriptor{Subject?=?new?ClaimsIdentity(new[]{new?Claim(JwtRegisteredClaimNames.Jti,?Guid.NewGuid().ToString("N")),new?Claim(JwtRegisteredClaimNames.Sub,?user.Id.ToString())}),IssuedAt?=?DateTime.UtcNow,NotBefore?=?DateTime.UtcNow,Expires?=?DateTime.UtcNow.Add(_jwtSettings.ExpiresIn),SigningCredentials?=?new?SigningCredentials(new?SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256Signature)};var?jwtTokenHandler?=?new?JwtSecurityTokenHandler();var?securityToken?=?jwtTokenHandler.CreateToken(tokenDescriptor);var?token?=?jwtTokenHandler.WriteToken(securityToken);return?new?TokenResult(){AccessToken?=?token,TokenType?=?"Bearer"}; }

注冊方法實現:

public?async?Task<TokenResult>?RegisterAsync(string?username,?string?password,?string?address) {var?existingUser?=?await?_userManager.FindByNameAsync(username);if?(existingUser?!=?null){return?new?TokenResult(){Errors?=?new[]?{"user?already?exists!"},?//用戶已存在};}var?newUser?=?new?AppUser()?{UserName?=?username,?Address?=?address};var?isCreated?=?await?_userManager.CreateAsync(newUser,?password);if?(!isCreated.Succeeded){return?new?TokenResult(){Errors?=?isCreated.Errors.Select(p?=>?p.Description)};}return?GenerateJwtToken(newUser); }

登錄方法實現:

public?async?Task<TokenResult>?LoginAsync(string?username,?string?password) {var?existingUser?=?await?_userManager.FindByNameAsync(username);if?(existingUser?==?null){return?new?TokenResult(){Errors?=?new[]?{"user?does?not?exist!"},?//用戶不存在};}var?isCorrect?=?await?_userManager.CheckPasswordAsync(existingUser,?password);if?(!isCorrect){return?new?TokenResult(){Errors?=?new[]?{"wrong?user?name?or?password!"},?//用戶名或密碼錯誤};}return?GenerateJwtToken(existingUser); }

最后,別忘了注冊UserService:

services.AddScoped<IUserService,?UserService>();

swagger配置

為了方便測試,可以配置一下swagger

NuGet安裝包:

<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />

ConfigureServices:

services.AddSwaggerGen(c?=> {c.SwaggerDoc("v1",?new?OpenApiInfo{Title?=?"Sample.Api",Version?=?"v1",Description?=?"Sample.Api?Swagger?Doc"});c.AddSecurityDefinition("Bearer",?new?OpenApiSecurityScheme{Description?=?"Input?the?JWT?like:?Bearer?{your?token}",Name?=?"Authorization",In?=?ParameterLocation.Header,Type?=?SecuritySchemeType.ApiKey,BearerFormat?=?"JWT",Scheme?=?"Bearer"});c.AddSecurityRequirement(new?OpenApiSecurityRequirement{{new?OpenApiSecurityScheme{Reference?=?new?OpenApiReference{Type?=?ReferenceType.SecurityScheme,Id?=?"Bearer"}},Array.Empty<string>()}}); });app.UseSwagger(); app.UseSwaggerUI(c?=>?c.SwaggerEndpoint("/swagger/v1/swagger.json",?"Sample.Api?v1"));

測試一下

隨便輸入abc進行注冊,返回了一些密碼規則的錯誤:

這個規則在注冊identity服務時可以配置:

services.AddIdentityCore<AppUser>(options?=> {options.Password.RequireDigit?=?true;options.Password.RequireLowercase?=?false;options.Password.RequireUppercase?=?false;options.Password.RequireNonAlphanumeric?=?false; }).AddEntityFrameworkStores<AppDbContext>();

identityOptions還支持一些其他配置。

下面注冊成功后返回了token:

使用剛剛注冊的賬號測試登錄,也沒有問題:

最后

本篇完成了identity的登錄,注冊,獲取token,下一篇將介紹如何使用refresh token。

參考:

ASP.NET Core 簡介 Identity | Microsoft Docs[1]

Mohamad Lawand - DEV Community[2]

參考資料

[1]

ASP.NET Core 簡介 Identity | Microsoft Docs: https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&tabs=visual-studio

[2]

Mohamad Lawand - DEV Community: https://dev.to/moe23/comments

總結

以上是生活随笔為你收集整理的使用identity+jwt保护你的webapi(二)——获取jwt token的全部內容,希望文章能夠幫你解決所遇到的問題。

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