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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

Asp.Net Core 5 REST API 使用 JWT 身份验证 - Step by Step(二)

發(fā)布時(shí)間:2023/12/4 asp.net 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Asp.Net Core 5 REST API 使用 JWT 身份验证 - Step by Step(二) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

翻譯自 Mohamad Lawand 2021年1月22日的文章?《Asp Net Core 5 Rest API Authentication with JWT Step by Step》?[1]

在本文中,我將向您展示如何向我們的 Asp.Net Core REST API 添加 JWT 身份驗(yàn)證。

我們將介紹的主題包含注冊(cè)、登錄功能以及如何使用?JWT (Json Web Tokens)[2]和 Bearer 身份驗(yàn)證。

你也可以在 YouTube 上觀看完整的視頻[3],還可以下載源代碼[4]。

這是 API 開發(fā)系列的第二部分,本系列還包含:

  • Part 1:Asp.Net Core 5 REST API - Step by Step

  • Part 3:Asp Net Core 5 REST API 中使用 RefreshToken 刷新 JWT - Step by Step

我們將基于上一篇文章中創(chuàng)建的 Todo REST API 應(yīng)用程序進(jìn)行當(dāng)前的講述,您可以通過閱讀上一篇文章并與我一起構(gòu)建應(yīng)用程序,或者可以從 github 下載上一篇中的源代碼。

前一篇文章中的代碼準(zhǔn)備好以后,就讓我們開始本文吧。

首先,我們需要安裝一些依賴包以使用身份驗(yàn)證:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore dotnet add package Microsoft.AspNetCore.Identity.UI

然后,我們需要更新?appsettings.json,在?appsettings?中添加 JWT 的設(shè)置部分,在該設(shè)置中添加一個(gè) JWT secret(密鑰)。

"JwtConfig": {"Secret" : "ijurkbdlhmklqacwqzdxmkkhvqowlyqa" },

為了生成 secret,我們可以使用一個(gè)免費(fèi)的 Web 工具(https://www.browserling.com/tools/random-string)來生成一個(gè)隨機(jī)的 32 個(gè)字符的字符串。

我們?cè)?appsettings?中添加完隨機(jī)生成的 32 個(gè)字符的字符串后,接著需要在根目錄中創(chuàng)建一個(gè)名為?Configuration?的新文件夾。

在這個(gè)?Configuration?文件夾中,我們將創(chuàng)建一個(gè)名為?JwtConfig?的新類:

public class JwtConfig {public string Secret { get; set; } }

現(xiàn)在我們需要更新?Startup?類,在?ConfigureServices?方法內(nèi),我們需要添加以下內(nèi)容,以便將 JWT 配置注入到應(yīng)用程序中:

services.Configure<JwtConfig>(Configuration.GetSection("JwtConfig"));

將這些配置添加到我們的?Startup?類中,即可在 Asp.Net Core 中間件和 IoC 容器中注冊(cè)配置。

下一步是在我們的?Startup?類中添加和配置身份驗(yàn)證,在我們的?ConfigureServices?方法中,我們需要添加以下內(nèi)容:

// 在本段中,我們將配置身份驗(yàn)證并設(shè)置默認(rèn)方案 services.AddAuthentication(options => {options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(jwt => {var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:Secret"]);jwt.SaveToken = true;jwt.TokenValidationParameters = new TokenValidationParameters {ValidateIssuerSigningKey = true, //這將使用我們?cè)?appsettings 中添加的 secret 來驗(yàn)證 JWT token 的第三部分,并驗(yàn)證 JWT token 是由我們生成的IssuerSigningKey = new SymmetricSecurityKey(key), //將密鑰添加到我們的 JWT 加密算法中ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,RequireExpirationTime = false}; });services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<ApiDbContext>();

更新好?ConfigureServices?之后,我們需要更新?Configure?方法,添加身份驗(yàn)證:

app.UseAuthentication();

配置添加完成后,我們需要構(gòu)建應(yīng)用程序,檢查是否所有的內(nèi)容都可以正常構(gòu)建:

dotnet build dotnet run

下一步是更新我們的?ApiDbContext,以便使用 Asp.Net 為我們提供的身份提供程序,導(dǎo)航到?Data?文件夾中的ApiDbContext,然后按以下內(nèi)容更新?ApiDbContext?類:

public class ApiDbContext : IdentityDbContext

通過從?IdentityDbContext?而不是?DbContext?繼承,EntityFramework 將知道我們正在使用身份驗(yàn)證,并且將為我們構(gòu)建基礎(chǔ)設(shè)施以使用默認(rèn)身份表。

要在我們的數(shù)據(jù)庫中生成身份表,我們需要準(zhǔn)備遷移腳本并運(yùn)行它們。也就是說,我們需要在終端中輸入并運(yùn)行以下命令:

dotnet ef migrations add "Adding authentication to our Api" dotnet ef database update

遷移完成后,我們可以使用 Dbeaver 打開數(shù)據(jù)庫?app.db,我們可以看到 EntityFramework 已經(jīng)為我們創(chuàng)建了身份表。

下一步是設(shè)置控制器并為用戶構(gòu)建注冊(cè)流程。我們需要在?Controllers?文件夾中創(chuàng)建一個(gè)新的控制器,并創(chuàng)建對(duì)應(yīng)的 DTO 類(Data Transfer Objects)。

先在根目錄中的?Configuration?文件夾中添加一個(gè)名為?AuthResult?的類:

// Configuration\AuthResult.cspublic class AuthResult {public string Token { get; set; }public bool Success { get; set; }public List<string> Errors { get; set; } }

然后我將添加一些文件夾來組織 DTOs,在?Models?文件夾中添加一個(gè)名為?DTOs?的文件夾,然后在此文件夾中創(chuàng)建兩個(gè)子文件夾?Requests?和?Responses。

我們需要添加供我們?cè)诳刂破髦械淖?cè) Action 使用的?UserRegistrationDto。導(dǎo)航到?Models/DTO/Requests,添加一個(gè)新類?UserRegistrationDto。

// Models\DTOs\Requests\UserRegistrationDto.cspublic class UserRegistrationDto {[Required]public string Username { get; set; }[Required][EmailAddress]public string Email { get; set; }[Required]public string Password { get; set; } }

添加?RegistrationResponse?響應(yīng)類。

// Models\DTOs\Responses\RegistrationResponse.cspublic class RegistrationResponse : AuthResult {}

現(xiàn)在,我們需要添加用戶注冊(cè)控制器,在控制器文件夾中添加一個(gè)新類,命名為?AuthManagementController,并使用以下代碼更新它:

// Controllers\AuthManagementController.cs[Route("api/[controller]")] // api/authmanagement [ApiController] public class AuthManagementController : ControllerBase {private readonly UserManager<IdentityUser> _userManager;private readonly JwtConfig _jwtConfig;public AuthManagementController(UserManager<IdentityUser> userManager, IOptionsMonitor<JwtConfig> optionsMonitor){_userManager = userManager;_jwtConfig = optionsMonitor.CurrentValue;}[HttpPost][Route("Register")]public async Task<IActionResult> Register([FromBody] UserRegistrationDto user){// 檢查傳入請(qǐng)求是否有效if(ModelState.IsValid){// 檢查使用相同電子郵箱的用戶是否存在var existingUser = await _userManager.FindByEmailAsync(user.Email);if(existingUser != null){return BadRequest(new RegistrationResponse(){Errors = new List<string>() {"Email already in use"},Success = false});}var newUser = new IdentityUser() { Email = user.Email, UserName = user.Username };var isCreated = await _userManager.CreateAsync(newUser, user.Password);if(isCreated.Succeeded){var jwtToken = GenerateJwtToken( newUser);return Ok(new RegistrationResponse() {Success = true,Token = jwtToken});} else {return BadRequest(new RegistrationResponse(){Errors = isCreated.Errors.Select(x => x.Description).ToList(),Success = false});}}return BadRequest(new RegistrationResponse(){Errors = new List<string>() {"Invalid payload"},Success = false});}private string GenerateJwtToken(IdentityUser user){//現(xiàn)在,是時(shí)候定義 jwt token 了,它將負(fù)責(zé)創(chuàng)建我們的 tokensvar jwtTokenHandler = new JwtSecurityTokenHandler();// 從 appsettings 中獲得我們的 secret var key = Encoding.ASCII.GetBytes(_jwtConfig.Secret);// 定義我們的 token descriptor// 我們需要使用 claims (token 中的屬性)給出關(guān)于 token 的信息,它們屬于特定的用戶,// 因此,可以包含用戶的 Id、名字、郵箱等。// 好消息是,這些信息由我們的服務(wù)器和 Identity framework 生成,它們是有效且可信的。var tokenDescriptor = new SecurityTokenDescriptor{Subject = new ClaimsIdentity(new []{new Claim("Id", user.Id), new Claim(JwtRegisteredClaimNames.Email, user.Email),new Claim(JwtRegisteredClaimNames.Sub, user.Email),// Jti 用于刷新 token,我們將在下一篇中講到new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())}),// token 的過期時(shí)間需要縮短,并利用 refresh token 來保持用戶的登錄狀態(tài),// 不過由于這只是一個(gè)演示應(yīng)用,我們可以對(duì)其進(jìn)行延長(zhǎng)以適應(yīng)我們當(dāng)前的需求Expires = DateTime.UtcNow.AddHours(6),// 這里我們添加了加密算法信息,用于加密我們的 tokenSigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)};var token = jwtTokenHandler.CreateToken(tokenDescriptor);var jwtToken = jwtTokenHandler.WriteToken(token);return jwtToken;} }

添加完注冊(cè)的 Action 后,我們可以在 Postman 中對(duì)其進(jìn)行測(cè)試并獲得 JWT token。

接下來是創(chuàng)建用戶登錄請(qǐng)求:

// Models\DTOs\Requests\UserLoginRequest.cspublic class UserLoginRequest {[Required][EmailAddress]public string Email { get; set; }[Required]public string Password { get; set; } }

然后,我們需要在?AuthManagementController?中添加?Login?方法:

[HttpPost] [Route("Login")] public async Task<IActionResult> Login([FromBody] UserLoginRequest user) {if(ModelState.IsValid){// 檢查使用相同電子郵箱的用戶是否存在var existingUser = await _userManager.FindByEmailAsync(user.Email);if(existingUser == null) {// 出于安全原因,我們不想透露太多關(guān)于請(qǐng)求失敗的信息return BadRequest(new RegistrationResponse(){Errors = new List<string>() {"Invalid login request"},Success = false});}// 現(xiàn)在我們需要檢查用戶是否輸入了正確的密碼var isCorrect = await _userManager.CheckPasswordAsync(existingUser, user.Password);if(!isCorrect) {// 出于安全原因,我們不想透露太多關(guān)于請(qǐng)求失敗的信息return BadRequest(new RegistrationResponse(){Errors = new List<string>() {"Invalid login request"},Success = false});}var jwtToken = GenerateJwtToken(existingUser);return Ok(new RegistrationResponse() {Success = true,Token = jwtToken});}return BadRequest(new RegistrationResponse(){Errors = new List<string>() {"Invalid payload"},Success = false}); }

現(xiàn)在,我們可以在 Postman 中對(duì)其進(jìn)行測(cè)試,我們將會(huì)看到 JWT token 已經(jīng)成功生成。

下一步是保護(hù)我們的控制器,需要做的就是向控制器添加?Authorize?屬性。

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] [Route("api/[controller]")] // api/todo [ApiController] public class TodoController : ControllerBase

此時(shí),如果我們?cè)賹?duì)?Todo?進(jìn)行測(cè)試,則由于未獲得授權(quán),我們將會(huì)無法執(zhí)行任何請(qǐng)求。為了發(fā)送帶授權(quán)的請(qǐng)求,我們需要添加帶有?Bearer token?的授權(quán) Header,以便 Asp.Net 可以驗(yàn)證它,并授予我們執(zhí)行操作的權(quán)限。

譯者注:
添加 Bearer token 請(qǐng)求頭的方法是:在 Headers 中,添加一個(gè)名稱為?Authorization?的 Header 項(xiàng),值為?Bearer <token>(需將?<token>?替換為真實(shí)的 token 值)。使用 Postman 測(cè)試時(shí),可參考 Postman 官方文檔:https://learning.postman.com/docs/sending-requests/authorization/#bearer-token。

至此,我們已經(jīng)完成了使用 JWT 為 REST API 添加身份驗(yàn)證的功能。

感謝您花時(shí)間閱讀本文。

本文是 API 開發(fā)系列的第二部分,本系列還包含:

  • Part 1:Asp.Net Core 5 REST API - Step by Step

  • Part 3:Asp Net Core 5 REST API 中使用 RefreshToken 刷新 JWT - Step by Step


相關(guān)鏈接:

  • https://dev.to/moe23/asp-net-core-5-rest-api-authentication-with-jwt-step-by-step-140d?Asp Net Core 5 Rest API Authentication with JWT Step by Step???

  • https://mp.weixin.qq.com/s/jnC8FDKm0Srj0ww-EvdUiw?JWT 介紹 - Step by Step???

  • https://youtu.be/LgpC4tYtc6Y???

  • https://github.com/mohamadlawand087/v7-RestApiNetCoreAuthentication???

  • 作者 :Mohamad Lawand
    譯者 :技術(shù)譯民
    出品 :技術(shù)譯站(https://ITTranslator.cn/)

    END

    總結(jié)

    以上是生活随笔為你收集整理的Asp.Net Core 5 REST API 使用 JWT 身份验证 - Step by Step(二)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。