JWT 是一种在网络中传输信息的开放标准 (RFC 7519),它可以将任意数据封装在一个安全的、自包含的、可验证的 token 中。该 token 包含了被称为“claims”的声明,用于描述 token 的持有者和其他相关信息。JWT 可以用于身份验证和授权,并且在许多领域中得到广泛应用。
.NET Core 内置了对 JWT 的支持,可以轻松地生成和验证 JWT。下面是一个简单的示例,演示如何使用 .NET Core 中的
JWT 来进行身份验证。
1.首先,我们需要安装 Microsoft.AspNetCore.Authentication.JwtBearer 包,
该包提供了在 .NET Core 中使用 JWT 进行身份验证所需的所有类和方法。
2.我们还需要一个密钥,用于加密和验证 JWT。我们可以使用 Rfc2898DeriveBytes 类生成随机的密钥。
以下代码片段演示了如何生成一个 32 字节的密钥:
using System.Security.Cryptography; byte[] key = new byte[32]; using (var generator = new Rfc2898DeriveBytes("my secret key", 16)) { key = generator.GetBytes(32); }
接下来,我们需要在 Startup.cs 中配置身份验证。我们将使用 JWT 进行身份验证,并将其作为默认的身份验证方案。
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; public void ConfigureServices(IServiceCollection services) { // 配置 JWT 身份验证 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//声明使用 JWT 进行身份验证。 .AddJwtBearer(options => { //TokenValidationParameters包含一组参数,用于验证 JWT 的有效性。 options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, //ValidIssuer 和 ValidAudience 是我们信任的 JWT 签发者和受众者。 ValidIssuer = "mydomain.com", ValidAudience = "mydomain.com", //IssuerSigningKey 是我们用于加密和验证 JWT 的密钥。 IssuerSigningKey = new SymmetricSecurityKey(key) }; }); // 其他配置 // ... } public void Configure(IApplicationBuilder app) { // 添加身份验证中间件 app.UseAuthentication(); // 其他中间件的注册和配置 }
现在我们已经配置了身份验证,我们需要在控制器中使用它来限制访问。我们可以使用 [Authorize] 特性来限制访问。下面是一个示例:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; [ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpGet] [Authorize] public IActionResult Get() { return Ok("Authenticated!"); } }
在这里,我们在 Get() 方法上使用了 [Authorize] 特性,该特性会限制只有经过身份验证的用户才能访问该方法。
现在我们需要生成 JWT 并将其发送给客户端,以便客户端可以在以后的请求中使用该 JWT 进行身份验证。以下是一个示例:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; [ApiController] [Route("[controller]")] public class MyController : ControllerBase { [HttpPost("login")] public IActionResult Login() { // 生成 JWT var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes("my secret key"); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "John Doe"), new Claim(ClaimTypes.Email, "john.doe@example.com") }), Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var jwt = tokenHandler.WriteToken(token); return Ok(new { jwt }); } [HttpGet] [Authorize] public IActionResult Get() { return Ok("Authenticated!"); } }
在这里,我们在 Login() 方法中生成 JWT,并将其作为 JSON 响应发送给客户端。我们使用 JwtSecurityTokenHandler 类来生成 JWT,该类需要一个 SecurityTokenDescriptor 对象作为参数,该对象包含 JWT 的声明和其他参数。在这里,我们声明了一个名为 John Doe 的用户和他的电子邮件地址,以及 JWT 的过期时间和签名密钥。
在 Get() 方法中,我们使用 [Authorize] 特性限制只有经过身份验证的用户才能访问该方法。当客户端发送包含 JWT 的请求时,JwtBearerAuthentication 中间件将自动验证该 JWT。
这就是 .NET Core 中使用 JWT 进行身份验证的基础知识。我们可以使用更复杂的配置和声明来满足各种需求,例如将自定义声明添加到 JWT 中,使用不同的算法进行签名和加密等等。
//services.AddHttpContextAccessor();IOC注入 IHttpContextAccessor private readonly IHttpContextAccessor _httpContextAccessor; public UserSession(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; }
上面为构造函数,依赖注入 _httpContextAccessor。
public async Task<int?> GetCurrUserIdAsync() { //获取登录用户的AuthenticateResult var auth = await _httpContextAccessor.HttpContext.AuthenticateAsync(); if (auth.Succeeded) { //在声明集合中获取ClaimTypes.NameIdentifier 的值就是用户ID var userCli = auth.Principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier); if (userCli == null || string.IsNullOrEmpty(userCli.Value)) { return null; } return Convert.ToInt32(userCli.Value); } return null; }
将上面登录的ToKen返回给前端,然后前端在把这个ToKen返回给后台
2016 © donet5.comApache Licence 2.0