背景
在近期的一个项目中需要做单点登录,除了登录服务、前端验证、分布式session的实现以外,还需要在程序中对每个API进行验证,Token编码使用JWT的方式。按我们的要求,需要在程序中实现4到5个检查点。其中还用到了多平台,平台代码需要从前端传递,程序中同样需要检查这一点。
目前要检查的点(API上有开启认证标签):
1. 是否传递认证头信息
2. 是否传递平台代码
3. 认证头中的token值解码失败
4. Token解码出来之后,sessionID为空或空字符串
5. sessionID在分布式session网络中是否有效
以上5个点有一个检查不过,都会报401错误,并且在响应头信息中中告诉它为什么。认证流程中当然不止上面5个点,但其它的部分会由另一个认证框架来实现,这里我们就控制不到了。
分析问题
上面5个点都是必须验证通过的,不存在有某个需求后可以跳过后面的步骤,所以不考虑执行顺序。另外一点,以后有没有添加新的认证需求呢?比如加入IP黑白名单?不使用JWT,使用别的传输方式?强制下线?所以这里我的设计思路是:
1. 在执行时调用一个方法来完成认证
2. 这个方法中调用不同的检查委托来认证
3. 检查委托是通过Func<T1,T2>模式添加到一个集合中的, T2中的检查方法只是遍历这个集合。
前面我们知道建造者模式是为了动态的去构建一个对象。那么在现在这个业务场景中,能不能把检查方法看成我们要构建的对象呢?我认为是可以的。因为检查方法主要是遍历Func这个集合,那么让向集合添加检查委托这一步动态起来就好了。
核心代码逻辑
1. 定义最后调用的东西
2. 编写添加子检查的代码
3. 构造方法中控制调用那些子检查。
定义检查委托集合
首先,会定义一个检查委托集合,检查方法会遍历执行它。
private readonlyList<Func<HttpContext, BizValidationError>> ChecFunckList;
//BizValidationError是我们自定义的一个错误消息类
调用:
定义检查委托集合
以检查平台为例:
构造方法中控制调用的检查
动态的关键点
关键点在于检查集合中的内容,是动态添加的。只要控制了这点,不管你怎么玩,都能很轻松的实现目标。
Java程序中怎么写?
C#程序中是利用委托来实现,而java中不像C#中有那样灵活的委托、内部方法这些,只能使用抽象或接口来实现了。编写逻辑:定义抽象检查方法->多个子类实现->有一个地方统一向检查集合中添加这些子类实例
真-动态
核心就在于怎么让检查集合获得这些委托,或者说“什么情况下添加什么委托”。这一点我们可以使用配置文件或配置系统实现了。例:代码中默认添加所有的逻辑进去,但是会按配置是否跳过这个检查。
总结
本文核心思想就是让我们的逻辑像变量一样,动态的增加进去。这一点和建造者模式的思想是比较类似的,我这里也是从建造者模式中得到启发的。当前这个业务场景中不存在要跳逻辑的情况,如果有可以使用责任链模式。
延伸与推荐
为了满足大家对.NET更高级内容的学习,我们精心准备了一套面向《.NET架构和高级进阶技术》的系统学习课程,课程核心内容如下:
《双十一期间,会连续免费7天提供精品录播和资料下载》
想领取免费资料或领取千元礼包的欢迎大家加我的微信:xiketang123
或扫描二维码加我即可