C# 基于微服务开发框架的设计思路(五)-登录验证和权限分离

        框架的设计,致力于最大程度减少程序员的技术要求和代码量,专心处理业务代码。微服务上线注册、系统的登录验证、API的权限验证登,在设计的时候,我们都不希望程序员去关注,那么从这里开始就简单说说控制器的基类的设计思想和大致的实现方法。

        首先是确定需求,控制器基类的核心:一是管道对请求的过滤和校验,二是路由和规则的制定。

        一、满足常规的增、删、改、查,标准化调用格式和标准化返回请求格式,标准化路由

        二、向系统管理微服务注册登记自身,包括API接口的说明

        三、登录和当前微服务没关系,每次请求API都要核对权限

        四、支持分布式事务(这里不再说明了),这里是封装了标准的几个API接口,且不显示在权限列表中的。

        五、支持扩展。

                1)启动时候的IStarter支持,在应用启动的时候能够加载额外的程序;

                2)额外API接口扩展,这个扩展很有用,起码看这么多项目,我是没有从其他项目中看到过。

        六、遗漏的异常处理。什么叫“遗漏”?就是业务层没有拦截到的异常信息,要在控制器中彻底拦截且保存日志,并通过API反馈到客户端。

        七、绑定当前登录用户的信息。注意,员工≠用户,这个是一对多的关系,同一个员工是可以同时拥有多个登录账号的,且不同账号可以属于不同角色,即拥有不同权限。所以登录后的账号要知道账号的拥有者是谁,就要绑定用户信息,例如员工编号、姓名等。

        八、恶意API请求的拦截。

        要满足上述需求,就需要好几个微服务来支持:SSO,OAuth,SystemMng。在我的框架中,没有使用任何第三方的框架。

        SSO的原理大致与IdentityServier差不多,也不完全一样。此微服务提供一整套用户注册、登录验证、修改用户信息、注销等一系列的接口,具体和哪个人没有关系。

        OAuth是属于System级别的,不同的系统拥有不同的权限,没必要搞在一起。此微服务只管验证是否有权限,提供验证的关键是api的请求链接的其中资源和方法部分,例如

        Get /api/Employee/GetPageList

        这里就验证了上述两个关键字,Get和/api/Employee/GetPageList,不区分大小写。

        SystemMng主要完成以下几样功能:第一系统级人机交互消息处理,例如后端产生的一些通知、错误、异常等;第二系统所属API的管理和前端菜单定义和现实配置(系统全局配置、用户操作习惯、报表模版管理等);

        其实这样的功能,在网上已经烂大街了,随便搜索一下都有。在这里写出来,只是一种探讨,不一定要遵守所谓的规矩来办事,自成一套体系。

        好了,准备工作都做好了,那么接下来就开干。应用启动的时候,获取本应用的id和所有API及其定义信息,向OAuth注册。把API的定义另外手工存成一个json文件。为什么不直接获取API的信息?其实Controller基类定义了很多基本接口,有些资源是不需要部分接口的,这样从json文件中就可以过滤掉部分不用到的标准接口。这么个工作就愉快完整了。OAuth如果重复收到相同apiid的注册信息,以最后一次收到的为准,且整体覆盖之前的注册信息。OAuth还提供一个handler给webapi使用,此handler放在api的管道中,拦截请求API的url,然后生成请求权限的数据,管道在得到权限许可后,就继续执行管道中的其他程序,否则直接报“无权限”,如果请求的API并未注册,则报“不存在接口”。对于恶意API请求,在在管道的最前端放置一个handler对请求数据进行拦截,设定一定规则,拦截恶意请求的用户或者地址。

        默认的 handler的调用过程  (外部请求)->防恶意请求->登录验证->权限验证->(API),括号部分不是管道执行的程序。当然也可以在控制器上做标注,以AOP的方式实现上述功能,但是从性能来讲,还是管道效率高,毕竟在管道中,请求还未涉及到控制器的任何代码,也就是说不会有任何实例化对象出现,如果使用在控制器上标注,这个时候,即使拒绝请求,控制器也已经实例化了。根本起不到保护作用。.

        其他的需求,都可以在管道中增加对应的处理程序来完成,这里就不一一说了,只说明一下额外API的扩展,这个功能确实比较少见。其有点在于业务可以更加抽象化,对于标准的业务接口,可以在主项目中完成,有变动的API接口,可以另外建立一个独立的项目文件,项目内容是独立的一组controller,通过框架的一个扩展方法,在应用启动的时候,如果是framework的api项目,则在Application_start事件中调用UseExtensionController(controllerDir)来动态加载控制器,只要在controllerDir目录中的扩展控制器,都会被加载进来。在Core下边,则在Service中加载即可。

        由于控制器基类项目中封装了标准的路由模板,遵守Restfull的标准格式,默认支持的谓词有:Option,Post,Put,Delete,Get这五中,其他一般也用不上,就没有封装进路由;跨域是必须得。可以说,程序员完全无需考虑这些复杂的API设置。控制器项目定义的是API接口,不允许编写具体的业务逻辑代码或者数据处理代码,严格来说,控制器就是一个API接口名称定义和数据中转。

        这样的扩展功能,对于二次开发来说也是非常实用的,不需要去修改原来Controller项目中的文件,直接可以增加API接口,且对原来的API没有任何影响。

        以上内容提到的功能,都封装在控制器基类中,程序员开发时候,只要继承基类编写一些特殊的接口或者重载基类接口方法就可以实现快速API,当构建控制器实体项目时候,可以直接通过CodeSmith模板自动生成对应的控制器,无需写任何其他动作了。

        至于程序员怎么启用基类中的基础配置,其实使用起来很简单。

在framework中,把所有的配置都封装到WebApiConfig类中,如果需要权限验证,怎使用WebTokenApiConfig,只要在Application_Start()事件中加入

GlobalConfiguration.Configure(WebTokenApiConfig.Register);

在dotnet Core中,在CreateHostBuilder方法中加载指定的Startup类即可

webBuilder.UseStartup<Startup>()

就可以直接使用基类中的所有配置,程序员对于整个API接口的配置都是透明的,特别是对于新手来说,是最方便的事情。框架设计目的就是降低程序员对各种技术要求的掌握程度,专注于业务逻辑开发,当然也不能完全不懂技术,只是降低要求而已,后续会对业务封装进行简单的分析和探讨。

        

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值