.Core3.1使用SwaggerApi的JWT token验证
1.目录结构
2.上代码
1)appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": {
//数据库地址链接 "DefaultConnection": "Data Source=localhost;Port=3306;User ID=root;Password=root; Initial Catalog=Offical;Charset=utf8; SslMode=none;Min pool size=1" }, "JwtIssuerOptions": { "Issuer": "AESCE", //发行人 "Audience": "AESCE",//订阅人 "ValidFor": 604800, "SecurityKey": "1ee65348-0a3d-11ec-bb18-8cec4b697def" //自定义密钥,记得设置长一点 } }
2)StartUp.cs
public class Startup { public IFreeSql FreeSql { get; private set; } public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; string connStr = Configuration.GetConnectionString("DefaultConnection"); this.FreeSql = new FreeSqlBuilder().UseConnectionString(DataType.MySql, connStr) .UseAutoSyncStructure(true) .UseLazyLoading(true) .UseNoneCommandParameter(true) .Build(); } //autofac 新增 public void ConfigureContainer(ContainerBuilder builder) { //业务逻辑层所在程序集命名空间 Assembly service = Assembly.Load("OfficalWebApi.Service");//注:webapi要引用接口和类,不然这边读不到 //接口层所在程序集命名空间 Assembly repository = Assembly.Load("OfficalWebApi.IService"); //自动注入 builder.RegisterAssemblyTypes(service, repository) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces(); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(c => { //只取一個 Action //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); c.SwaggerDoc("v1", new OpenApiInfo { Title = "OfficalWebApi接口文档", Version = "v1" }); var xmlFile = $"{ Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath, true);//添加控制器层注释(true表示显示控制器注释) var xmlFile2 = $"{ Assembly.GetExecutingAssembly().GetName().Name}.Model.xml"; var xmlPath2 = Path.Combine(AppContext.BaseDirectory, xmlFile2); c.IncludeXmlComments(xmlPath2, true);//添加控制器层注释(true表示显示控制器注释) #region JWT验证 //开启权限验证 c.OperationFilter<AddResponseHeadersFilter>(); c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>(); //在header钟添加token,传递到后台 c.OperationFilter<SecurityRequirementsOperationFilter>(); c.AddSecurityDefinition("oauth2",new OpenApiSecurityScheme { Description = "JWT授权(数据将在请求头钟进行传递)直接在下面框中输入:Bearer Token(注意两者之间是一个空格)", Name = "Authorization",//jwt默认参数名 In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中) Type = SecuritySchemeType.ApiKey, BearerFormat = "JWT", Scheme = "Bearer" }); #endregion }); //添加jwt验证 services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { //获取appsettings配置值 var jwtmodel = Configuration.GetSection(nameof(JwtIssuerOptions)); var iss = jwtmodel[nameof(JwtIssuerOptions.Issuer)]; var key = jwtmodel[nameof(JwtIssuerOptions.SecurityKey)]; var audience = jwtmodel[nameof(JwtIssuerOptions.Audience)]; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true,//是否验证Issuer ValidateAudience = true,//是否验证Audience ValidateLifetime = true, //是否验证失效时间 ValidateIssuerSigningKey = true,//是否验证SecurityKey RequireExpirationTime = true, ClockSkew = TimeSpan.Zero,//默认允许300s的时间偏移量,设置为0 ValidAudience = audience,//订阅人 ValidIssuer = iss,//发行人,这两项和后面签发jwt的设置一致 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)) }; }); services.AddControllers(); //注入freesql services.AddSingleton(this.FreeSql); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication();//这里顺序很重要 app.UseAuthorization(); //配置Swagger接口页面 app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "RFIDBaseDataApiV1"); }); //指向Swagger接口静态页面 //DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions(); //defaultFilesOptions.DefaultFileNames.Clear(); //defaultFilesOptions.DefaultFileNames.Add("/Swagger/Index.html"); //app.UseDefaultFiles(defaultFilesOptions); app.UseStaticFiles(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } }
注:这里.Core3.1安装的JWT需要用3.1版本及以下的,最新版安装不上
3)帮助类CommonHelper.cs(Token 解析需要Nutget安装 jose-jwt)
/// <summary> /// 帮助类 /// </summary> public class CommonHelper { /// <summary> /// 根据用户获取token /// </summary> /// <returns></returns> public string GetTokenByUser(LoginModel model, IConfiguration Configuration) { var jwtModel = Configuration.GetSection(nameof(JwtIssuerOptions)); //颁发者 var issuer = jwtModel[nameof(JwtIssuerOptions.Issuer)]; var key = jwtModel[nameof(JwtIssuerOptions.SecurityKey)]; //接收者 var audience = jwtModel[nameof(JwtIssuerOptions.Audience)]; //参数 var claims = new List<Claim> { new Claim(JwtRegisteredClaimNames.Iat,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddMilliseconds(1000)).ToUnixTimeSeconds()}"), new Claim(JwtRegisteredClaimNames.Iss,issuer), new Claim(JwtRegisteredClaimNames.Aud,audience),
new Claim(ClaimTypes.Role,"Admin"),
new Claim("Id",model.Id.ToString()),
new Claim("UserName",model.UserName)
};//一个用户多个角色
//claims.AddRange(model.Roles.Split(",").Select(s => new Claim(ClaimTypes.Role, s))) var m5dkey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); var creds = new SigningCredentials(m5dkey,SecurityAlgorithms.HmacSha256);//生成签名 var jwttoken = new JwtSecurityToken( issuer : issuer, audience:audience, claims:claims, expires:DateTime.Now.AddMinutes(30), signingCredentials:creds ); var token = new JwtSecurityTokenHandler().WriteToken(jwttoken);//生成token return token; }
/// <summary>
/// 解析token获取用户信息
/// </summary>
///<returns></returns>
public User DesUserToken(string token, IConfiguration Configuration)
{
var userInfo = Jose.JWT.Payload<User>(token.Replace("Bearer ",""));
return userInfo;
}
}
4)Controllers
/// <summary> /// 用户操作接口 /// </summary> [Route("api/[controller]")] [ApiController] public class UserController : ControllerBase { private readonly IUserService _userService; private readonly IConfiguration _configuration; public UserController(IUserService userService, IConfiguration configuration) { _userService = userService; _configuration = configuration; } /// <summary> /// 根据Id获取用户信息 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet("GetUserById")] [Authorize] public ResultModel GetUserById(string id) { return _userService.GetUserById(id); } /// <summary> /// 用户登录 /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost("LoginUser")] public ResultModel LoginUser(LoginModel model) { ResultModel result = new ResultModel(); //获取用户 var user = _userService.GetUserInfo(model); if (user != null && user.Id != null) { model.Id = user.Id; CommonHelper commonHelper = new CommonHelper(); var token = commonHelper.GetTokenByUser(model, _configuration); result.Data = new { token }; result.SetSuccess(); } else result.SetFail("账号密码错误!"); return result; }
5)使用
①使用登录接口获取token
②点击右上角Authorize,输入 【Bearer token】 =》这里的token 是赋值①的
Bearer Token
③Close后就可以正常进行操作了
分享:有个JWT的token官网验证地址:https://jwt.io/
感谢:https://blog.csdn.net/qq_20258573/article/details/108726983
https://www.cnblogs.com/nwdnote/p/13554202.html
https://blog.csdn.net/qq_20258573/article/details/108727344
https://blog.csdn.net/weixin_42873937/article/details/82460997
https://blog.csdn.net/crazyxiaoyuge/article/details/109057779