Bootstrap

Asp.Net Core 3.X使用 Swagger + jwt模式

什么是Swagger?什么是jwt?

Swagger就是一个查看api接口的一个文档工具,方便使用测试,你可以理解为方法都被罗列出来,而且postman测试的输入方法url的过程也被解析了,省事。
jwt是一个认证授权的工具,json web token,它相较于传统session,cookie这种较麻烦承载认证的验证方式更方便。

怎么使用Swagger+jwt?

1.引用nuGet 包

Swashbuckle.AspNetCore -Swagger
Swashbuckle.AspNetCore.Filters -Swagger
Microsoft.AspNetCore.Authentication.JwtBearer --JWT

2.IOC容器注册此 俩个 服务

3.配置 中间件

4.jwt需要一个登录方法来实现token,从而达到认证效果

怎么注册服务和配置中间价?

内置的服务和中间件都是这样的

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
        }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

你会发现比较简洁,在于都是封装好的,不会有复杂的代码,都是一句话Add… app…
所以一般来讲 配置服务和中间件都要封装一下 避免在看上去很多代码。

怎么封装?

1.首先建一个 Extension文件夹 为了统一管理好找
2.建立相应名称含义的类 此案例取名为 JwtSwaggerEx.cs
3.写相应处理代码 下方有代码段
(涉及AppSettings读取配置文件的代码)获取配置文件内容
4.startup类直接调用封装方法

第三步骤封装代码片段,共3个方法 AddSwaggerEx /AddJwtEx /UseSwaggerEx

 public static class JwtSwaggerEx
    {
        /// <summary>
        /// Swagger注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="modular"></param>
        /// <param name="docs"></param>
        /// <returns></returns>
        public static IServiceCollection AddSwaggerEx(this IServiceCollection services)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "方便测试API", Version = "v1" });
                // Set the comments path for the Swagger JSON and UI.
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                c.IncludeXmlComments(xmlPath);
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme{
                                Reference = new OpenApiReference {
                                            Type = ReferenceType.SecurityScheme,
                                            Id = "Bearer"}
                           },new string[] { }
                        }
                    });
            });
            return services;
        }

        public static IServiceCollection AddJwtEx(this IServiceCollection services)
        {         services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    //Token颁发机构
                    ValidIssuer = AppSettings.JwtSetting.Issuer,
                    //颁发给谁
                    ValidAudience = AppSettings.JwtSetting.Audience,
                    //这里的key要进行加密,需要引用Microsoft.IdentityModel.Tokens
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.JwtSetting.SecurityKey)),
                    //ValidateIssuerSigningKey=true,
                    //是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
                    ValidateLifetime = true,
                    //允许的服务器时间偏移量
                    ClockSkew = TimeSpan.Zero
                };
            });
            return services;
        }
        
        public static IApplicationBuilder UseSwaggerEx(this IApplicationBuilder app)
        {
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "基础接口");
            });
            return app;
        }
    }

第4步在ConfigureServices 和 Configure 中 加入使用

          services.AddSwaggerEx();
          services.AddJwtEx();
          app.UseSwaggerEx();

这样swagger+jwt配置就完成了! 启动效果如下:

在这里插入图片描述

接下来如何 让jwt的认证 起到作用呢,需要写一个Login登录方法 让token生产

该方法的参数都是模拟的,实际的话可以通过数据库验证用户名密码

 [AllowAnonymous]
        [HttpGet]
        public string Login(string username, string password)
        {
            
            var claims = new Claim[]
            {
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim("id", "ceshi", ClaimValueTypes.Integer32), // 用户id
                new Claim("name", "ceshi"), // 用户名
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettings.JwtSetting.SecurityKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            //创建令牌
            var token = new JwtSecurityToken(
              issuer: AppSettings.JwtSetting.Issuer,
              audience: AppSettings.JwtSetting.Audience,
              signingCredentials: creds,
              claims: claims,
              notBefore: DateTime.Now,
              expires: DateTime.Now.AddSeconds(AppSettings.JwtSetting.ExpireSeconds)
            );

            string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);

            return jwtToken;
        }

然后开始使用jwt的功能
1:先用一下swagger 方便测试一下 Login方法 得到token的值
在这里插入图片描述
在这里插入图片描述
2.将token 输入到认证框中
在这里插入图片描述
在这里插入图片描述
3.这样就token生效了,然后测试别的 控制器中的方法 如果方法特性加了
[Authorize] 就会被去验证,如果你不去把Token给加上的话,就过不去会报401错误。
在这里插入图片描述
OK,这样的话就完成了 认证!

注意:1 如果要xml 注释的话 也就是方法中///中的注释显示到swagger上 项目 右键属性 -生成 把xml勾上 不然找不到
2 如果想启动项目就是swagger 就在launchSettings.json 中 设置"launchUrl": “swagger” 不然可能是index控制器

;