如何使用Swagger为.NET Core 3.0应用添加JWT授权说明文档
简介
本教程采用why-what-how黄金圈思维模式编写,黄金圈法则强调的是从why为什么学,到what学到什么,再到how如何学。从模糊到清晰的学习模式。大家的时间都很宝贵,我们做事前先想清楚为什么要做,学完能达到什么样的目标,然后我们再考虑要达到这个目的,通过什么样的方法来实现。
尝试一些事,遭遇失败后从中学习,比什么事都不做更好。—马克.佐克伯
为什么要学?
对于开发人员来说,调试api接口和生成api文档是一件极其头疼的事情。我们在百忙之中,还不得不为前端开发人员编写接口文档,来描述系统中n个接口的参数及返回状态,再借助postman等第三方工具来测试api的正确性。在swagger诞生后,这项体力活终于得到了极大的改善,我们不但可以自动构建漂亮的交互式api说明文档,还可以直接调试api接口的正确性。最新版的swagger已经完美支持open api规范及jwt token授权访问等。
能学到什么?
- 使用 swagger 生成精美的api接口文档
- 使用 swagger 调试jwt授权接口
- 使用 swagger 生成各个类库中视图模型的描述
怎么做?
swagger项目开源地址:https://github.com/domaindrivendev/swashbuckle.aspnetcore
创建一个.net core项目
首先,新建一个.net core 3.0 web api 项目,打开nuget安装管理器,勾选左下角的显示预览发行包,搜索swashbuckle.aspnetcore,版本选择5.0.0-rc4的点添加,注意因为.net core 3.0刚出不久,目前支持的库很多都是预览版,这里我选5.0.0-beta是会报错,选5.0.0-rc4使用正常。
设置生成xml描述信息
耐心等待几秒钟添加完成后,我们选中左侧刚才创建的api项目,右键>属性(mac里叫选项),勾选生成xml文档,这个是用来生成为swagger所用的描述信息。
开始配置swagger
然后我们打开startup.cs文件,来对swagger配置进行一些必要的配置,在configureservices方法我们添加一下swagger配置:
services.addswaggergen(c => { c.swaggerdoc("v1", new openapiinfo { version = "v1", title = "crypto exchange", description = "基于.net core 3.0 的区块链数字货币交易所", contact = new openapicontact { name = "microfisher", email = "276679490@qq.com", url = new uri("http://cnblogs.com/microfisher"), }, }); // 加载程序集的xml描述文档 var basedirectory = system.appdomain.currentdomain.basedirectory; var xmlfile = system.appdomain.currentdomain.friendlyname+ ".xml"; var xmlpath = path.combine(basedirectory, xmlfile); c.includexmlcomments(xmlpath); })
参数都很简单,就是swagger界面上显示的一些信息,注意这里一定要习惯使用path.combine来拼接路径,很多同学喜欢双斜杠来拼接,在mac和linux下是会出问题的,既然已经拥抱开源技术,尽量使用mac或linux来开发.net core吧。然后我们在configure方法里添加以下代码:
app.useswagger(); app.useswaggerui(c => { c.swaggerendpoint("/swagger/v1/swagger.json", "crypto exchange"); // 访问swagger的路由后缀 c.routeprefix = "swagger"; });
预览一下小成果
到这里为止,我们的swagger的最基本的配置就完成了,其中routeprefix是访问swagger的路由,如果设置为空则不需要输入/swagger后缀来访问。现在我们f5启动项目看看,我的本地网址是https://localhost:5000,所以直接访问:https://localhost:5000/swagger如下图所示,我去这界面也太丑了,说好的精美绝伦呢?不急不急,我们慢慢调优:
启用api文档的jwt授权
目前很多网站都使用了jwt(json web token)来作为账户系统的认证授权,jwt以它的简单、高效、分布式优势很快成为了网站的流行验证方式。这里我们不做过多的介绍,如果大家感兴趣我可以再写一篇长文来介绍jwt的优势和使用方法。我们继续来为swagger添加jwt授权认证,依旧打开startup.cs文件,修改上面configureservices方法中的代码:
services.addswaggergen(c => { c.swaggerdoc("v1", new openapiinfo { version = "v1", title = "crypto exchange", description = "基于.net core 3.0 的区块链数字货币交易所", contact = new openapicontact { name = "microfisher", email = "276679490@qq.com", url = new uri("http://cnblogs.com/microfisher"), }, }); 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[] { } } }); var basedirectory = system.appdomain.currentdomain.basedirectory; var xmlfile = system.appdomain.currentdomain.friendlyname + ".xml"; var xmlpath = path.combine(basedirectory, xmlfile); c.includexmlcomments(xmlpath); });
预览一下授权设置
然后再启动项目,你会发现右侧多了一个authorize绿色的带锁按钮,这个按钮点开后就可以设置我们的jwt token信息了,格式是:bearer 你的token字符串,注意bearer于token之间有个空格。设置好token后,你请求任意的api接口时,swagger会自动附带token到请求的header中。
创建一个restful接口
上面我们已经实现了swagger的各项配置,现在我们来删除默认生成的控制器weatherforecastcontroller及视图模型weatherforecast,新建一个accountcontroller及几个视图模型,让swagger返回带描述的接口文档。
//[authorize] [produces("application/json")] [route("v1/[controller]")] [apicontroller] public class accountcontroller : controllerbase { /// <summary> /// 创建信息 /// </summary> /// <param name="createviewmodel">参数</param> /// <returns>状态</returns> [httppost] public statusviewmodel post([frombody]createviewmodel createviewmodel) { return new statusviewmodel { }; } /// <summary> /// 删除信息 /// </summary> /// <param name="deleteviewmodel">参数</param> /// <returns></returns> [httpdelete] public statusviewmodel delete([fromquery]deleteviewmodel deleteviewmodel) { return new statusviewmodel { }; } /// <summary> /// 查询信息 /// </summary> /// <param name="queryviewmodel">参数</param> /// <returns></returns> [httpget] public statusviewmodel get([fromquery]queryviewmodel queryviewmodel) { return new statusviewmodel { }; } /// <summary> /// 修改信息 /// </summary> /// <param name="updateviewmodel">参数</param> /// <returns></returns> [httpput] public statusviewmodel put([fromquery]updateviewmodel updateviewmodel) { return new statusviewmodel { }; } }
创建几个视图模型
再按自己喜欢的风格新建几个视图模型,用///为各个字段添加summary后如下:
public class updateviewmodel { /// <summary> /// id /// </summary> public long id { get; set; } /// <summary> /// 账号 /// </summary> public long account { get; set; } /// <summary> /// 密码 /// </summary> public long password { get; set; } }
测试最终成果
最后我们来看看效果,随便展开一个api接口,可以看到我们给视图模型写的注释已经显示在swagger上了,前端开发人员一看就懂,输入一些接口参数,点一下执行就能看到返回值了:
再看我们的请求header中已经包含了jwt授权信息(bearer 123456789)是我随意设置的,让你们前端调试的时候换成你们的token就行了。