聊城做网站的公司效果,无锡做家纺公司网站,全国行业名录搜索系统,类似百度的网站翻译自 Mohamad Lawand 2021年1月22日的文章 《Asp Net Core 5 Rest API Authentication with JWT Step by Step》 [1]在本文中#xff0c;我将向您展示如何向我们的 Asp.Net Core REST API 添加 JWT 身份验证。我们将介绍的主题包含注册、登录功能以及如何使用 JWT (Json Web… 翻译自 Mohamad Lawand 2021年1月22日的文章 《Asp Net Core 5 Rest API Authentication with JWT Step by Step》 [1]在本文中我将向您展示如何向我们的 Asp.Net Core REST API 添加 JWT 身份验证。我们将介绍的主题包含注册、登录功能以及如何使用 JWT (Json Web Tokens)[2]和 Bearer 身份验证。你也可以在 YouTube 上观看完整的视频[3]还可以下载源代码[4]。这是 API 开发系列的第二部分本系列还包含Part 1Asp.Net Core 5 REST API - Step by StepPart 3Asp Net Core 5 REST API 中使用 RefreshToken 刷新 JWT - Step by Step我们将基于上一篇文章中创建的 Todo REST API 应用程序进行当前的讲述您可以通过阅读上一篇文章并与我一起构建应用程序或者可以从 github 下载上一篇中的源代码。前一篇文章中的代码准备好以后就让我们开始本文吧。首先我们需要安装一些依赖包以使用身份验证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 的设置部分在该设置中添加一个 JWT secret密钥。JwtConfig: {Secret : ijurkbdlhmklqacwqzdxmkkhvqowlyqa
},
为了生成 secret我们可以使用一个免费的 Web 工具https://www.browserling.com/tools/random-string来生成一个随机的 32 个字符的字符串。我们在 appsettings 中添加完随机生成的 32 个字符的字符串后接着需要在根目录中创建一个名为 Configuration 的新文件夹。在这个 Configuration 文件夹中我们将创建一个名为 JwtConfig 的新类public class JwtConfig
{public string Secret { get; set; }
}
现在我们需要更新 Startup 类在 ConfigureServices 方法内我们需要添加以下内容以便将 JWT 配置注入到应用程序中services.ConfigureJwtConfig(Configuration.GetSection(JwtConfig));
将这些配置添加到我们的 Startup 类中即可在 Asp.Net Core 中间件和 IoC 容器中注册配置。下一步是在我们的 Startup 类中添加和配置身份验证在我们的 ConfigureServices 方法中我们需要添加以下内容// 在本段中我们将配置身份验证并设置默认方案
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, //这将使用我们在 appsettings 中添加的 secret 来验证 JWT token 的第三部分并验证 JWT token 是由我们生成的IssuerSigningKey new SymmetricSecurityKey(key), //将密钥添加到我们的 JWT 加密算法中ValidateIssuer false,ValidateAudience false,ValidateLifetime true,RequireExpirationTime false};
});services.AddDefaultIdentityIdentityUser(options options.SignIn.RequireConfirmedAccount true).AddEntityFrameworkStoresApiDbContext();
更新好 ConfigureServices 之后我们需要更新 Configure 方法添加身份验证app.UseAuthentication();
配置添加完成后我们需要构建应用程序检查是否所有的内容都可以正常构建dotnet build
dotnet run
下一步是更新我们的 ApiDbContext以便使用 Asp.Net 为我们提供的身份提供程序导航到 Data 文件夹中的ApiDbContext然后按以下内容更新 ApiDbContext 类public class ApiDbContext : IdentityDbContext
通过从 IdentityDbContext 而不是 DbContext 继承EntityFramework 将知道我们正在使用身份验证并且将为我们构建基础设施以使用默认身份表。要在我们的数据库中生成身份表我们需要准备迁移脚本并运行它们。也就是说我们需要在终端中输入并运行以下命令dotnet ef migrations add Adding authentication to our Api
dotnet ef database update
迁移完成后我们可以使用 Dbeaver 打开数据库 app.db我们可以看到 EntityFramework 已经为我们创建了身份表。下一步是设置控制器并为用户构建注册流程。我们需要在 Controllers 文件夹中创建一个新的控制器并创建对应的 DTO 类Data Transfer Objects。先在根目录中的 Configuration 文件夹中添加一个名为 AuthResult 的类// Configuration\AuthResult.cspublic class AuthResult
{public string Token { get; set; }public bool Success { get; set; }public Liststring Errors { get; set; }
}
然后我将添加一些文件夹来组织 DTOs在 Models 文件夹中添加一个名为 DTOs 的文件夹然后在此文件夹中创建两个子文件夹 Requests 和 Responses。我们需要添加供我们在控制器中的注册 Action 使用的 UserRegistrationDto。导航到 Models/DTO/Requests添加一个新类 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 响应类。// Models\DTOs\Responses\RegistrationResponse.cspublic class RegistrationResponse : AuthResult
{}
现在我们需要添加用户注册控制器在控制器文件夹中添加一个新类命名为 AuthManagementController并使用以下代码更新它// Controllers\AuthManagementController.cs[Route(api/[controller])] // api/authmanagement
[ApiController]
public class AuthManagementController : ControllerBase
{private readonly UserManagerIdentityUser _userManager;private readonly JwtConfig _jwtConfig;public AuthManagementController(UserManagerIdentityUser userManager, IOptionsMonitorJwtConfig optionsMonitor){_userManager userManager;_jwtConfig optionsMonitor.CurrentValue;}[HttpPost][Route(Register)]public async TaskIActionResult Register([FromBody] UserRegistrationDto user){// 检查传入请求是否有效if(ModelState.IsValid){// 检查使用相同电子邮箱的用户是否存在var existingUser await _userManager.FindByEmailAsync(user.Email);if(existingUser ! null){return BadRequest(new RegistrationResponse(){Errors new Liststring() {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 Liststring() {Invalid payload},Success false});}private string GenerateJwtToken(IdentityUser user){//现在是时候定义 jwt token 了它将负责创建我们的 tokensvar jwtTokenHandler new JwtSecurityTokenHandler();// 从 appsettings 中获得我们的 secret var key Encoding.ASCII.GetBytes(_jwtConfig.Secret);// 定义我们的 token descriptor// 我们需要使用 claims token 中的属性给出关于 token 的信息它们属于特定的用户// 因此可以包含用户的 Id、名字、邮箱等。// 好消息是这些信息由我们的服务器和 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 的过期时间需要缩短并利用 refresh token 来保持用户的登录状态// 不过由于这只是一个演示应用我们可以对其进行延长以适应我们当前的需求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;}
}
添加完注册的 Action 后我们可以在 Postman 中对其进行测试并获得 JWT token。接下来是创建用户登录请求// 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 TaskIActionResult Login([FromBody] UserLoginRequest user)
{if(ModelState.IsValid){// 检查使用相同电子邮箱的用户是否存在var existingUser await _userManager.FindByEmailAsync(user.Email);if(existingUser null) {// 出于安全原因我们不想透露太多关于请求失败的信息return BadRequest(new RegistrationResponse(){Errors new Liststring() {Invalid login request},Success false});}// 现在我们需要检查用户是否输入了正确的密码var isCorrect await _userManager.CheckPasswordAsync(existingUser, user.Password);if(!isCorrect) {// 出于安全原因我们不想透露太多关于请求失败的信息return BadRequest(new RegistrationResponse(){Errors new Liststring() {Invalid login request},Success false});}var jwtToken GenerateJwtToken(existingUser);return Ok(new RegistrationResponse() {Success true,Token jwtToken});}return BadRequest(new RegistrationResponse(){Errors new Liststring() {Invalid payload},Success false});
}
现在我们可以在 Postman 中对其进行测试我们将会看到 JWT token 已经成功生成。下一步是保护我们的控制器需要做的就是向控制器添加 Authorize 属性。[Authorize(AuthenticationSchemes JwtBearerDefaults.AuthenticationScheme)]
[Route(api/[controller])] // api/todo
[ApiController]
public class TodoController : ControllerBase
此时如果我们再对 Todo 进行测试则由于未获得授权我们将会无法执行任何请求。为了发送带授权的请求我们需要添加带有 Bearer token 的授权 Header以便 Asp.Net 可以验证它并授予我们执行操作的权限。译者注添加 Bearer token 请求头的方法是在 Headers 中添加一个名称为 Authorization 的 Header 项值为 Bearer token需将 token 替换为真实的 token 值。使用 Postman 测试时可参考 Postman 官方文档https://learning.postman.com/docs/sending-requests/authorization/#bearer-token。至此我们已经完成了使用 JWT 为 REST API 添加身份验证的功能。感谢您花时间阅读本文。本文是 API 开发系列的第二部分本系列还包含Part 1Asp.Net Core 5 REST API - Step by StepPart 3Asp Net Core 5 REST API 中使用 RefreshToken 刷新 JWT - Step by Step相关链接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译者 技术译民出品 技术译站https://ITTranslator.cn/END