1、JWT:
JWT,即JSON Web Token,是一个开放标准,用于在各方之间安全地传输信息。以下是它的详细介绍:
- 结构:JWT由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature)。头部通常由两部分组成:令牌的类型(通常为“JWT”)和所使用的签名算法,例如HMAC SHA256或RSA。载荷包含声明(Claims),这些是关于实体(通常是用户)和其他数据的信息。签名是对头部和载荷的加密,确保令牌在传输过程中未被篡改。
- 用途:JWT主要用于在网络环境中传递安全信息,尤其是在身份验证和授权场景中。它可以作为HTTP请求头的一部分发送,或者嵌入到URL中。由于JWT是自包含的,它可以减少对服务器存储的依赖,因为服务器不需要保留与令牌相关的会话信息。
- 工作原理:当客户端请求服务时,服务端会验证客户端提供的JWT。如果JWT有效且签名正确,服务端会处理请求。否则,将拒绝服务。这个过程保证了只有持有正确JWT的用户才能访问受保护的资源。
- 优势:JWT的主要优势在于其简单性和可移植性。它不依赖于服务器端的会话存储,因此可以更容易地实现跨域解决方案。此外,由于JWT是无状态的,它可以减少服务器的内存使用,提高可扩展性。
总的来说,JWT是一种灵活、安全且易于实现的身份验证方法,适用于现代Web应用程序和服务。
使用:
讯飞星火:
在.NET Core中,使用JWT(JSON Web Tokens)可以为Web API添加身份验证和授权。以下是如何在.NET Core Web API中使用JWT的步骤:
- 安装JWT相关的NuGet包:您需要在项目中安装
System.IdentityModel.Tokens.Jwt
包,以及用于处理JWT的第三方库,如Microsoft.AspNetCore.Authentication.JwtBearer
。- 配置JWT认证服务:在
Startup.cs
文件的ConfigureServices
方法中,需要添加JWT认证服务,并配置相关的选项,如密钥、算法和过期时间等。- 配置授权策略:在
Startup.cs
文件的Configure
方法中,使用app.UseAuthorization
来启用授权中间件,并定义哪些控制器或操作需要JWT认证。- 创建令牌生成和验证方法:创建一个类,用于生成JWT令牌,并在需要的地方调用这个类的方法来生成令牌。同时,需要创建一个方法来验证令牌的有效性。
- 用户登录和注册:在用户登录时,验证用户的凭据,如果成功,则生成一个JWT令牌并返回给客户端。客户端在后续的请求中需要在HTTP头部的
Authorization
字段中携带这个令牌。- 处理令牌过期:在服务器端,需要处理JWT令牌过期的情况。通常,这涉及到捕获特定的异常,并向客户端返回适当的错误信息。
- 客户端使用JWT:客户端在接收到JWT令牌后,应该在每次向服务器发送请求时都在HTTP头部的
Authorization
字段中包含该令牌。- 安全性考虑:确保使用HTTPS来保护JWT令牌在传输过程中的安全,避免令牌被截获。
- 日志和监控:为了安全起见,应该记录JWT的生成、验证和使用情况,以便于问题追踪和安全审计。
- 测试:在实际部署之前,彻底测试JWT的生成、验证和授权流程,确保没有安全漏洞。
- 文档和教育:为开发者和维护人员提供关于如何使用和处理JWT的文档指导,以确保正确和一致的使用。
总的来说,上述步骤是一个基本的指南,具体的实现可能会根据您的项目需求和技术栈有所不同。在使用JWT时,需要考虑到安全性和可维护性,确保系统的整体安全。
我们使用他主要是为了方便控制接口的访问权限,以及登录人信息的获取
2、 安装nuget包:Microsoft.AspNetCore.Authentication.JwtBearer
3、代码
3.1、配置文件
/* JWT配置 */
"JWT": {
"ValidIssuer": "plateau.poetize.blog.Issuer",
"ValidAudience": "plateau.poetize.blog.Audience",
"IssuerSigningKey": "cGxhdGVhdS5wb2V0aXplLmJsb2cud2ViYXBpLmp3dC5Jc3N1ZXJTaWduaW5nS2V5"
}
3.2、模型
/// <summary>
/// JWT json配置文件模型
/// </summary>
public class JwtOptions
{
public string ValidIssuer { get; set; }
public string ValidAudience { get; set; }
public string IssuerSigningKey { get; set; }
}
public class JwtClaim
{
public string Id { get; set; }
public string NickName { get; set; }
public string Name { get; set; }
public string UserType { get; set; }
public string Roles { get; set; }
public string Menus { get; set; }
}
3.3、注入:
#region JWT
var validIssuer = AppSettings.app(new string[] { "JWT", "ValidIssuer" });
var validAudience = AppSettings.app(new string[] { "JWT", "ValidAudience" });
var issuerSigningKey = AppSettings.app(new string[] { "JWT", "IssuerSigningKey" });
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = validIssuer, // 发行者
ValidAudience = validAudience, // 接收方
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(issuerSigningKey)) // 密钥
};
});
#endregion
app.UseAuthentication();
app.UseAuthorization();
3.4、service:
public class JwtService : IJwtService
{
private readonly string _issuer = AppSettings.app(new string[] { "JWT", "ValidIssuer" });
private readonly string _audience = AppSettings.app(new string[] { "JWT", "ValidAudience" });
private readonly string _key = AppSettings.app(new string[] { "JWT", "IssuerSigningKey" });
public JwtService(string issuer, string audience, string secretKey)
{
_issuer = issuer;
_audience = audience;
_key = secretKey;
}
public string GenerateToken(JwtClaim jwtClaim)
{
var claims = new[]
{
new Claim("Id",jwtClaim.Id),
new Claim("NickName",jwtClaim.NickName),
new Claim("Name",jwtClaim.Name),
new Claim("UserType",jwtClaim.UserType),
//权限
new Claim("Roles",jwtClaim.Roles),
new Claim("Menus",jwtClaim.Menus),
};
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
var jmType = SecurityAlgorithms.HmacSha256Signature;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddMinutes(120), // 设置过期时间(120分钟)
Issuer = _issuer,
Audience = _audience,
SigningCredentials = new SigningCredentials(symmetricSecurityKey, jmType)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
var result = tokenHandler.WriteToken(token);
return result;
}
public bool ValidateToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
try
{
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key));
var parameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = symmetricSecurityKey,
ValidateIssuer = true,
ValidIssuer = _issuer,
ValidateAudience = true,
ValidAudience = _audience,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero // 严格验证过期时间
};
tokenHandler.ValidateToken(token, new TokenValidationParameters(), out SecurityToken validatedToken);
return validatedToken is JwtSecurityToken jwtToken && jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature);
}
catch (Exception)
{
return false;
}
}
}
3.5、测试:Controller层
/// <summary>
/// Jwt 控制器
/// </summary>
[ApiVersionCustomRoute(SwaggerDocSettings.ApiVersions.v1)]
[ApiController]
public class JwtController : ControllerBase
{
private readonly IJwtService _iJwtService;
private readonly ILogger<JwtController> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="iJwtService"></param>
/// <param name="logger"></param>
public JwtController(IJwtService iJwtService, ILogger<JwtController> logger)
{
_iJwtService = iJwtService;
_logger = logger;
}
/// <summary>
/// 生成Token
/// </summary>
/// <param name="jwtClaim">jwtClaim模型(构造Claim)</param>
/// <returns></returns>
[HttpPost]
public ApiResult GenerateToken(JwtClaim jwtClaim)
{
var token = _iJwtService.GenerateToken(jwtClaim);
return ApiResultHelper.Success(token);
}
/// <summary>
/// 验证Token
/// </summary>
/// <param name="token">token</param>
/// <returns></returns>
[HttpPost]
public ApiResult ValidateToken(string token)
{
var bl = _iJwtService.ValidateToken(token);
return ApiResultHelper.Success(bl);
}
/// <summary>
/// 测试权限
/// </summary>
/// <returns></returns>
[HttpGet]
[Authorize]
public string Test()
{
return "ok!";
}
}