.Net6 Api Swagger配置

1、定义个Swagger版本(组)的枚举

namespace WebApp.Enums
{/// <summary>/// api版本枚举/// </summary>public enum ApiVersion{/// <summary>/// v1版本/// </summary>v1 = 1,/// <summary>/// v2版本/// </summary>v2 = 2,}
}

2、添加SwaggerExtentsion扩展类,配置注册Swagger

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Net.Http.Headers;
using System.Net;
using System.Reflection;
using System.Text;
using WebApp.Enums;namespace WebApp.Common.Swagger
{/// <summary>/// SwaggerDoc配置/// 用法:在Program.cs文件中进行注册:builder.AddSwaggerGenExt();/// </summary>public static class SwaggerExtension{/// <summary>/// 扩展方法:Swagger文档/// </summary>/// <param name="services"></param>public static void AddSwaggerGenExt(this IServiceCollection services){#region 添加Swagger//获取的是当前执行的方法所在的程序文件的名称:即项目名称,例如我的项目名称叫webapp var AssemblyName = Assembly.GetExecutingAssembly().GetName().Name;services.AddSwaggerGen(options =>{#region 配置版本//options.SwaggerDoc("v1", new OpenApiInfo { Title = "售楼API", Version = "v1" });typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>{options.SwaggerDoc(version, new OpenApiInfo(){Version = version,Title = "凤凰网管理系统",Description = $"凤凰网接口服务    版本: {version}",Contact = new OpenApiContact{Name = "潇湘夜雨",Email = "123@qq.com"}});});#endregion#region 配置注释文档// 获取当前项目的 XML文档文件路径:比如我的项目名称叫WebApp,那么它默认的 XML文档文件路径就是当前项目下的 WebApp.xmlvar xmlFile = $"{AssemblyName}.xml";var xmlFileFullPath = Path.Combine(AppContext.BaseDirectory, xmlFile);//var domainXmlPath = Path.Combine(AppContext.BaseDirectory, "Bgy.Domain.xml");      // 获取Bgy.Domain.xml文件路径//var viewmodelXmlPath = Path.Combine(AppContext.BaseDirectory, "Bgy.ViewModel.xml");// 获取Bgy.ViewModel.xml文件路径options.IncludeXmlComments(xmlFileFullPath, true); // 添加控制器层注释,true表示显示控制器注释//options.IncludeXmlComments(domainXmlPath);       // 添加Domain层注释//options.IncludeXmlComments(viewmodelXmlPath);    // 添加ViewModel层注释//对action的名称进行排序。options.OrderActionsBy(o => o.RelativePath);#endregion#region 配置授权认证信息//添加一个必须的全局安全信息,//第一个参数是方案唯一名称:和AddSecurityDefinition方法指定的方案名称标识一致即可:BearerAuth//第二个参数是方案的描述:可以是BasicAuthScheme、ApiKeyScheme的实例或OAuth2Schemeoptions.AddSecurityDefinition("BearerAuth", new OpenApiSecurityScheme(){Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",Name = "Authorization",In = ParameterLocation.Header, //配置jwt默认加在Authorization信息的位置:这里配置的是将jwt信息放在请求头Header中            Type = SecuritySchemeType.Http,//使用Authorize头部                  Scheme = "bearer", //内容为以 bearer开头BearerFormat = "JWT",//Reference= new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "bearerAuth" }});//注册全局认证(所有的接口都可以使用认证)options.AddSecurityRequirement(new OpenApiSecurityRequirement(){{new OpenApiSecurityScheme{Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme,Id = "BearerAuth" //方案名称标识}},new string[] {} //不设权限}});#endregion#region 在Swagger中扩展文件上传按钮options.OperationFilter<FileUploadFilter>();#endregion});#endregion}/// <summary>/// 扩展方法:配置SwaggerUI/// 用法:在Program.cs文件中进行注册:app.UseSwaggerUIExt();/// </summary>/// <param name="app"></param>public static void UseSwaggerUIExt(this WebApplication app){//SwaggerBasicAuthMiddleware:是我自己扩展的一个中间件:目的是需要登陆才能到达Swagger的Index页面中,否则无法进入:可以根据需要去掉这个//需要安装:Swashbuckle.AspNetCore包//app.UseMiddleware<SwaggerBasicAuthMiddleware>();if (app.Environment.IsDevelopment()){//app.UseSwagger();//app.UseSwaggerUI();}var enviroment = app.Configuration["Swagger:environmentVariables"];switch (enviroment){case "development":app.UseSwagger();//启用Swagger中间件app.UseSwaggerUI(options =>  //配置版本{typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>{options.SwaggerEndpoint($"/swagger/{version}/swagger.json", version);});});break;case "testing":app.UseSwagger();app.UseSwaggerUI(options =>{typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>{options.SwaggerEndpoint($"/swagger/{version}/swagger.json", version);});});break;case "production":break;}}}#region 扩展功能/// <summary>/// 文件上传的扩展:实现在Swagger中上传文件的功能/// </summary>public class FileUploadFilter : IOperationFilter{/// <summary>/// 文件上传筛选:只有上传文件的方法才添加此功能/// </summary>/// <param name="operation"></param>/// <param name="context"></param>public void Apply(OpenApiOperation operation, OperationFilterContext context){const string FileUploadContentType = "multipart/form-data";if (operation.RequestBody == null || !operation.RequestBody.Content.Any(x => x.Key.Equals(FileUploadContentType, StringComparison.InvariantCultureIgnoreCase))){return;}if (context.ApiDescription.ParameterDescriptions[0].Type == typeof(IFormCollection)){operation.RequestBody = new OpenApiRequestBody{Description = "文件上传",Content = new Dictionary<string, OpenApiMediaType>{{FileUploadContentType,new OpenApiMediaType{Schema=new OpenApiSchema{Type="object",Required=new HashSet<string>{ "file"},Properties=new Dictionary<string, OpenApiSchema>{{"file",new OpenApiSchema{Type="string",Format="binary"}}}}}}}};}}}/// <summary>/// 如何在ASP.Net Core的生产环境中保护swagger ui,也就是index.html页面。其实swagger是自带禁用的功能的,只需要设置开关即可。/// 但是有一些场景,是需要把这些接口进行开放或者导出成文档供第三方进行调用,这个时候却又不想让所有人访问。/// 这里介绍一种权限控制访问的方式,用来指定用户使用;/// </summary>public class SwaggerBasicAuthMiddleware{private readonly RequestDelegate next;/// <summary>/// 增加对swagger ui的验证/// </summary>/// <param name="next"></param>public SwaggerBasicAuthMiddleware(RequestDelegate next){this.next = next;}/// <summary>/// 登陆功能实现/// </summary>/// <param name="context"></param>/// <returns></returns>public async Task InvokeAsync(HttpContext context){if (context.Request.Path.StartsWithSegments("/swagger")){string authHeader = context.Request.Headers["Authorization"];if (authHeader != null && authHeader.StartsWith("Basic ")){// Get the credentials from request headervar header = AuthenticationHeaderValue.Parse(authHeader);var inBytes = Convert.FromBase64String(header.Parameter);var credentials = Encoding.UTF8.GetString(inBytes).Split(':');var username = credentials[0];var password = credentials[1];//用户身份认证if (username.Equals("admin") && password.Equals("123456")){await next.Invoke(context).ConfigureAwait(false);return;}}context.Response.Headers["WWW-Authenticate"] = "Basic";context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;}else{await next.Invoke(context).ConfigureAwait(false);}}}#endregion
}

3、appsettings.json配置文件

{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*","Swagger": {"environmentVariables": "development" //:development  :testing  :production}
}

4、在Program.cs中注册SwaggerDoc及启用SwaggerUI

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using WebApp.Common.Swagger;var builder = WebApplication.CreateBuilder(args);builder.Services.AddControllers();builder.Services.AddEndpointsApiExplorer();#region JWT鉴权授权
var audience = "Audience";
var issuer = "Issuer";
var securityKey = "SIGfMA0FCSqGSIb3DFEBAQUAA4GNADCBiQKBgQDI2a2EJ7d872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI593nNDAPfnJsas96mSA9Q/mD8RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  //默认授权机制名称;                                      .AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = true,//是否验证IssuerValidateAudience = true,//是否验证AudienceValidateLifetime = true,//是否验证失效时间ValidateIssuerSigningKey = true,//是否验证SecurityKeyValidAudience = audience,//AudienceValidIssuer = issuer,//Issuer,这两项和前面签发jwt的设置一致  表示谁签发的TokenIssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey))//拿到SecurityKey};});
#endregionbuilder.Services.AddSwaggerGenExt();//SwaggerGenvar app = builder.Build();app.UseSwaggerUIExt(); //SwaggerUIapp.UseAuthentication();app.UseAuthorization();app.MapControllers();app.Run();

5、Api接口中使用

在接口控制器,或者方法上添加版本(组)标识:[ApiExplorerSettings(GroupName = "v1")]

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using WebApp.Enums;namespace WebApp.Controllers
{/// <summary>/// 测试接口/// </summary>[ApiController]//[ApiController]能够推断参数的绑定源,就不需要[FromBody][FromForm][FromHeader][FromQuery][FromRoute]....来主动指定接收参数的形式[Route("api/[controller]/[action]")]public class HomeController : ControllerBase{private readonly ILogger<HomeController> _logger;/// <summary>/// 构造函数/// </summary>/// <param name="logger"></param>public HomeController(ILogger<HomeController> logger){_logger = logger;}/// <summary>/// 查询案列1/// </summary>/// <param name="id">编号</param>/// <returns></returns>[HttpGet("Abc")] //url地址是:api/WeatherForecast/Get/Abc[ApiExplorerSettings(GroupName = "v1")][Authorize]public IActionResult Get(int id){return Ok(id);//返回值:IActionResult//return NotFound(); 404//return Redirect("/Home/Index");//var content = "Hello, World!";//return Content(content, "text/plain");//var data = new { Name = "John", Age = 30 };//return Json(data);//var filePath = "/path/to/file.pdf";//return File(filePath, "application/pdf", "filename.pdf");//byte[] videoBytes = System.IO.File.ReadAllBytes(containerPath);//return File(videoBytes, "video/mp4");}/// <summary>/// 查询案列2:路由的伪静态/// </summary>/// <param name="name"></param>/// <returns></returns>[HttpGet("Abc/{name}")] //url地址是:api/WeatherForecast/Get/Abc/lily   :lily是name值, 同时name值是必填的,{name}必须要与action的参数名称一致。这就是路由的伪静态形式[ApiExplorerSettings(GroupName = nameof(ApiVersion.v1))][Authorize]public IActionResult Get(string name){return Ok(name);}/// <summary>/// 客户端登陆/// </summary>/// <param name="clientid">客户端名称</param>/// <param name="password">客户端密码</param>/// <returns>返回jwtToken</returns>[HttpGet][ApiExplorerSettings(GroupName = nameof(ApiVersion.v2))][Route("api/login")]public IActionResult Login(string clientid, string password){//这里肯定是需要去连接数据库做数据校验if (clientid == "admin" && password == "123456")//应该数据库{string token = GetJwtToken(clientid);return Ok(new { token });}else{return Ok("");}}/// <summary>/// 获取Token/// </summary>/// <param name="UserName"></param>/// <returns></returns>[NonAction]public string GetJwtToken(string UserName){var issuer = "Issuer";var audience = "Audience";var securityKey = "SIGfMA0FCSqGSIb3DFEBAQUAA4GNADCBiQKBgQDI2a2EJ7d872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI593nNDAPfnJsas96mSA9Q/mD8RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB";Claim[] claims = new[]{new Claim(ClaimTypes.Name, UserName)};SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(securityKey));SigningCredentials creds = new(key, SecurityAlgorithms.HmacSha256);var token = new JwtSecurityToken(issuer: issuer,audience: audience,claims: claims,expires: DateTime.Now.AddMinutes(1),//5分钟有效期signingCredentials: creds);return new JwtSecurityTokenHandler().WriteToken(token);}/// <summary>/// 文件上传/// </summary>/// <param name="from"></param>/// <returns></returns>[HttpPost]public JsonResult UploadFile(IFormCollection from){return new JsonResult(new{Success = true,Message = "上传成功",FileName = from.Files.FirstOrDefault()?.FileName}) ;     }/// <summary>/// 标记了[NonAction]特性,则不被视为控制器的操作方法/// </summary>/// <param name="id"></param>/// <returns></returns>[HttpPost(Name = "{id}")][NonAction]public string PostTest(int id){return id.ToString();}}
}

6、项目配置生成XML文件

7、效果图

7、注意点:

如果只是单纯只返回token的时候,记得在控制器右上角的Authorize里  先写Bearer+空格+你的token 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/152602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端面试考核点【更持续新中】

文章目录 HTMLcssjsVueReactTypeScript移动端&小程序编译/打包/构建npmnodejs微前端网络安全浏览器性能OKR工程化、标准化 HTML Script放在body中间会阻塞吗&#xff1f;defer与async的区别&#xff1f;https://blog.csdn.net/qq_41887214/article/details/124909219 DOM和…

内存学习(4):内存分类与常用概念3(ROM)

1 ROM介绍 ROM即为只读存储器&#xff0c;全拼是Read Only Memory。 1.1 “只读”的由来 ROM叫只读存储器是因为最早的ROM&#xff08;MROM&#xff09;确实是只能读取不能写入&#xff0c;一旦出厂不能再写&#xff0c;需要在出厂之前预设好它的数据&#xff0c;并且它是掉…

十四、Docker的基本操作

目录 &#xff08;一&#xff09;镜像命令 一、拉取Nginx 二、查看镜像 三、导出文件 四、删除镜像 五、加载镜像 &#xff08;二&#xff09;容器命令 一、例子&#xff1a;运行一个nginx容器 1、输入运行命令 2、使用命令查看宿主机ip 3、在外部浏览器访问 4、查看…

【机器学习】037_暂退法

一、实现原理 具有输入噪音的训练&#xff0c;等价于Tikhonov正则化 核心方法&#xff1a;在前向传播的过程中&#xff0c;计算每一内部层的同时注入噪声 从作用上来看&#xff0c;表面上来说是在训练过程中丢弃一些神经元 假设x是某一层神经网络层的输出&#xff0c;是下一…

redhat下使用CentOS yum源,并安装docker

一、安装yum源 1.卸载yum # 查看系统自身安装的yum软件包 rpm -qa | grep yum # 卸载软yum件包 rpm -e 软件包名称 --nodeps #可以使用简称如 rpm -e yum-* --nodeps2. 安装yum [rootbogon ~]# rpm -ivh --nodeps https://mirrors.aliyun.com/centos/8/BaseOS/x86_64/os/Pa…

海康Visionmaster-环境配置:运行出现 Vm.Core.Solu tion 报错的解决方法

&#xff08;1&#xff09;检查加密狗有没有插好&#xff1f; 是否以管理员权限启动程序&#xff1f;首选 32 位是否取消勾选&#xff1f; &#xff08;2&#xff09;查看 VM4.0 的版本信息是否为最新版本&#xff1f;版本信息为 20220415 以上&#xff0c;版本越新问题就会越少…

【机器学习】036_权重衰退

一、范数 定义&#xff1a;向量的范数表示一个向量有多大&#xff08;分量的大小&#xff09; L1范数&#xff1a; 即向量元素绝对值之和&#xff0c;用符号 ‖ v ‖ 1 表示。 公式&#xff1a; L2范数&#xff1a; 即向量的模&#xff0c;向量各元素绝对值的平方之和再…

低代码平台技术分享官 | 漫话iGIX前端设计模式

设计模式是一个程序员进阶高级的必备技巧&#xff0c;也是评判一个工程师工作经验和能力的试金石。设计模式是程序员多年工作经验的凝练和总结&#xff0c;能够更大限度的优化代码以及对已有代码进行合理重构。但如果你还不知道如何使用设计模式提升前端开发质量&#xff0c;那…

MQTT协议详解

前言 MQTT是一个即时通讯协议&#xff0c;它工作在TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。它使用发布/订阅消息模式&#xff0c;提供一对多的消息发布&#xff0c;解除应用程序耦合。MQTT是轻量、简单、…

适合您的智能手机的 7 款优秀手机数据恢复软件分享

如今&#xff0c;我们做什么都用手机&#xff1b;从拍照到录音&#xff0c;甚至作为 MP3 播放器&#xff0c;我们已经对手机变得非常依恋。这导致我们在手机上留下了很多珍贵的回忆。 不幸的是&#xff0c;我们有可能会丢失手机上的部分甚至全部数据。幸运的是&#xff0c;这不…

1. hadoop环境准备

环境准备 准备三台虚拟机&#xff0c;配置最好是 2C 4G 以上 本文准备三台机器的内网ip分别为 172.17.0.10 172.17.0.11 172.17.0.12本机配置/etc/hosts cat >> /etc/hosts<<EOF 172.17.0.10 hadoop01 172.17.0.11 hadoop02 172.17.0.12 hadoop03 EOF本机设置与…

队列的实现和OJ练习

目录 概念 队列的实现 利用结构体存放队列结构 为什么单链表不使用这种方法&#xff1f; 初始化队列 小提示&#xff1a; 队尾入队列 队头出队列 获取队头元素 获取队尾元素 获取队列中有效元素个数 检测队列是否为空 销毁队列 最终代码 循环队列 队列的OJ题 …

C++-特殊类和单例模式

1.请设计一个类&#xff0c;不能被拷贝 拷贝构造函数以及赋值运算符重载&#xff0c;因此想要让一个类禁止拷贝&#xff0c;只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 //该类不能发生拷贝class NonCopy{public:NonCopy(const NonCopy& Nc) delete;NonCopy&…

MobaXterm如何连接CentOS7的Linux虚拟机?Redis可视化客户端工具如何连接Linux版Redis?

一、打开Lunix虚拟机,进入虚拟机中,在终端中输入ifconfig,得到以下信息&#xff0c;红框中为ip地址 二、打开MobaXterm&#xff0c;点击session 选择SSH&#xff0c;在Remote host中输入linux得到的IP地址&#xff0c;Specify username中可起一个任意的连接名称。 输入密码 四、…

AM@傅里叶级数@周期为2l的一般情形

文章目录 abstract周期为 2 l 2l 2l的Fourier展开推导例 三角函数和(-1)的幂转换关系(-1)的幂与级数的奇偶项级数通项变形例例 abstract 从特殊到一般,从对周期为 2 π 2\pi 2π的函数到周期为 2 l 2l 2l的函数 推导周期为 2 l 2l 2l情况下的公式又可以借助于周期为 2 π 2\pi…

【洛谷 P3743】kotori的设备 题解(二分答案+递归)

kotori的设备 题目背景 kotori 有 n n n 个可同时使用的设备。 题目描述 第 i i i 个设备每秒消耗 a i a_i ai​ 个单位能量。能量的使用是连续的&#xff0c;也就是说能量不是某时刻突然消耗的&#xff0c;而是匀速消耗。也就是说&#xff0c;对于任意实数&#xff0c;…

60 权限提升-MYMSORA等SQL数据库提权

目录 数据库应用提权在权限提升中的意义WEB或本地环境如何探针数据库应用数据库提权权限用户密码收集等方法目前数据库提权对应的技术及方法等 演示案例Mysql数据库提权演示-脚本&MSF1.UDF提权知识点: (基于MYSQL调用命令执行函数&#xff09;读取数据库存储或备份文件 (了…

记录 ubuntu 硬盘分区跟格式化(fdisk命令)

1、sudo su 2、fdisk -l 查找需要挂载的硬盘是哪一个 3、fdisk /dev/sda 可以输入m&#xff0c;查看帮助信息&#xff0c;按p&#xff0c;查看磁盘分区信息 输入n&#xff0c;选择分两个区&#xff08;原来已经有一个&#xff0c;再加1个就是2两个&#xff09;&#xff0c…

GaussDB新特性Ustore存储引擎介绍

1、 Ustore和Astore存储引擎介绍 Ustore存储引擎&#xff0c;又名In-place Update存储引擎&#xff08;原地更新&#xff09;&#xff0c;是openGauss 内核新增的一种存储模式。此前的版本使用的行存储引擎是Append Update&#xff08;追加更新&#xff09;模式。相比于Append…

在网络攻击之前、期间和之后应采取的步骤

在当今复杂的威胁形势下&#xff0c;网络攻击是不可避免的。 恶意行为者变得越来越复杂&#xff0c;出于经济动机的攻击变得越来越普遍&#xff0c;并且每天都会发现新的恶意软件系列。 这使得对于各种规模和跨行业的组织来说&#xff0c;制定适当的攻击计划变得更加重要。 …