北京突现狂风暴雨福州seo技巧培训
1. 定义实体类
首先,定义一个与 JSON 配置结构匹配的实体类 JWTSetting用读取存放配置文件的值。
public class JWTSetting{public string SecretKey { get; set; }public int ExpireHours { get; set; }}
2. 配置 appsettings.json
确保你的 appsettings.json 文件中有如下配置:
"JWTSettingOption": {"SecretKey": "thisistolongcode,andthishavestory@123321:KH>:&(*","ExpireHours": 10}
3. 在 Program.cs 中注册配置
var builder = WebApplication.CreateBuilder(args);// 绑定配置并注册到依赖注入容器builder.Services.Configure<JWTSetting>(builder.Configuration.GetSection("JWTSettingOption"));builder.Services.AddAuthentication(opt =>{opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(opt =>{var jwtSetting = builder.Configuration.GetSection("JWTSettingOption").Get<JWTSetting>();opt.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.SecretKey))};});builder.Services.AddJWTService(); // 自定义builder.Services.AddAuthorization();// 在Swagger中可以像Hearder中添加 Authorization属性,用来传递JWT Tokenbuilder.Services.AddSwaggerGen(c =>{var scheme = new OpenApiSecurityScheme(){Description = "JWT Authorization header using the Bearer scheme",Reference = new OpenApiReference{Id = "Authorization",Type = ReferenceType.SecurityScheme},In = ParameterLocation.Header,Type = SecuritySchemeType.ApiKey,Scheme = "oauth2",Name = "Authorization",};c.AddSecurityDefinition("Authorization", scheme);var requirement = new OpenApiSecurityRequirement();requirement[scheme] = new List<string>();c.AddSecurityRequirement(requirement);});// 使用身份验证中间件 必须在UseAuthorization之前app.UseAuthentication(); // 使用授权中间件app.UseAuthorization();
4. 使用依赖注入获取JWT服务配置
在需要使用配置的地方,通过构造函数注入 IOptionsSnapshot 来访问配置。
// 接口public interface IJWTService{/// <summary>/// Generate token/// </summary>/// <param name="userId"></param>/// <param name="userName"></param>/// <returns></returns>string GenerateToken(long userId, string userName);}// 实现类服务
public class JWTService : IJWTService
{private readonly IOptionsSnapshot<JWTSetting> _settings;public JWTService(IOptionsSnapshot<JWTSetting> settings){_settings = settings;}/// <summary>/// Generate token/// </summary>/// <param name="userId"></param>/// <param name="userName"></param>/// <returns></returns>public string GenerateToken(long userId, string userName){// 生成秘钥实例var secretKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(_settings.Value.SecretKey));// 生成签名凭证var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);// 生成声明集合var claims = new System.Collections.Generic.List<System.Security.Claims.Claim>{new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.Name, userName),new System.Security.Claims.Claim(System.Security.Claims.ClaimTypes.NameIdentifier, userId.ToString())};// 生成过期时间var expiresDate = DateTime.Now.AddHours(_settings.Value.ExpireHours);// 生成 tokenvar token = new JwtSecurityToken(claims: claims, signingCredentials: signingCredentials, expires: expiresDate);// 生成 token 字符串var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);return tokenStr;}}/// <summary>/// 自定义依赖注入帮助类/// </summary>public static class DIHelper{/// <summary>/// 添加IServiceCollection 自定义扩展函数 JWT 服务/// </summary>/// <param name="services"></param>/// <returns></returns>public static IServiceCollection AddJWTService(this IServiceCollection services){return services.AddScoped<IJWTService, JWTService>();}}
5. 测试代码
使用 JWTTestController 进行登录检查。
[Route("api/[controller]/[action]")]
[ApiController]
public class JWTTestController
{private readonly IJWTService _jwtService;private readonly UserManager<MyUser> _userManager;private readonly RoleManager<MyRole> _roleManager;public JWTTestController(IJWTService jwtService, UserManager<MyUser> userManager, RoleManager<MyRole> roleManager){_jwtService = jwtService;_userManager = userManager;_roleManager = roleManager;}/// <summary>/// 登录/// </summary>/// <param name="login"></param>/// <returns></returns>[HttpPost]public async Task<IActionResult> Login([FromBody] LoginModel login){var user = await _userManager.FindByNameAsync(login.UserName);if (user == null){return new JsonResult(new { Code = 400, Message = "用户不存在" });}if (!await _userManager.CheckPasswordAsync(user, login.Password)){return new JsonResult(new { Code = 400, Message = "密码错误" });}var token = _jwtService.GenerateToken(user.Id, user.UserName);return new JsonResult(new { Code = 200, Message = "登录成功", Token = token });}
}
使用 TestController进行权限检查,添加[Authorize]注解,校验当前方法必须校验Token。
[Route("api/[controller]/[action]")][ApiController]public class TestController{private readonly UserManager<MyUser> _userManager;private readonly RoleManager<MyRole> _roleManager;public TestController(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager){_userManager = userManager;_roleManager = roleManager;}// AllowAnonymous不校验该权限[HttpGet][AllowAnonymous]public async Task<ActionResult<string>> CheckAccount(string account, string password){var user = await _userManager.FindByNameAsync(account);if (user == null){return "错误";}else{return "正确";}}// 校验当前必须是admin权限才能操作[HttpPost][Authorize(Roles ="admin")]public async Task<ActionResult<string>> CreateUser(string account, string password){var user = await _userManager.FindByNameAsync(account);if (user == null){user = new MyUser{UserName = account};var result = await _userManager.CreateAsync(user, password);if (!result.Succeeded){return "创建失败";}}var role = await _roleManager.FindByNameAsync("admin");if (role == null){role = new MyRole{Name = "admin"};var result = await _roleManager.CreateAsync(role);if (!result.Succeeded){return "创建失败";}}var result2 = await _userManager.AddToRoleAsync(user, "admin");return "成功";}}