第一部分讲完了整体的技术架构,
总结:
项目文件结构解释
AutoMapper 加速开发流程
Cache 自建或者选用CacheMemory
Samesite设置以及数据库连接池提高性能
使用FluentValidation检测API参数拦截
启动压缩提高效率
Swagger提供文档下面,将对某些核心业务规范和相关实现做出解释;
一,数据库用户权限设计
采用角色分权设定,分为权限分配表和角色表;
角色表大类分层设计,同层级类别无法相互操作,低层级无法操作高层级;

id为key,State表示当前状态,ApiName表示具体的Api调用名,可调用的是Role为200的用户;
值得注意的是,我们把Api方法名赋值给Role角色,这样实现了给用户不同角色即可改变用户权限,这里还需要设计的是权限大类间隔,管理员可能会会各种权限,此时,需求要多加一种管理员,和管理员类似但肯定是不同的,此时,假设管理员Role表示为1000, 那么这个新的管理员就设置为1001;类似的如果还有,就设置为1002,用一个区间来表示某个权限大类,这样的好处我理解为,如果权限要重置或者要管理,可以方便抽取和重新混合构建,不影响其他大类分段里的权限分配;当然还有其他更多的优势,比如同层级不能互操,A和B都属于管理员,属于1000-2000,A不能对B修改权限等,底层级不能对高层级进行操作,您总不想一个普通用户对超级管理员说 “ f**k u “ 吧;

在Number_Role字段设置大类区间;为什么不做更精细的设计?当你做更精细的设计的时候,回过头发现,只要大类需求变动,要控制和更改的太多!而且,本人所经历的公司或者大部分人所经历的公司,大多都是敏捷开发【先搞出来,后面有机会再重构(这里的有机会一般就是没机会)】,大公司可能会明确的知道业务,还有各种环节来确定流程和规范,大把的时间设计,我们没有哦。
然后,数据库表设计的时候,抽出公共字段,比如已出现的或者可能所有的表都会出现的字段,比如State,TimeCreate,Timestamp等,这里的Timestamp是提供数据库并发情况下,防止数据出错,那么这里又将引发另一个问题,如果数据库层级操作数据失败怎么处理,这里的处理肯定是EFCore处理,但是,我们肯定要给客户端提示呀,是否记得Startup.cs中AddMvc中添加了 o.Filters.Add(new GlobalExceptionFilter());,然后,我们在该类下实现一个GlobalExceptionFileter类,它实现IExceptionFilter接口

二,登录篇
用户登录后,我们进行什么操作呢?
生产Session,保存登录用户???还有吗?? 当然这里需要还需要考虑是否保存用户的其他信息??是否需要把登录的用户信息存入某些缓存中??是否有三方事件订阅等等;
此时,调用Controller中的登录协议,登录协议是任何角色都可以调用的,但是登录后验证时,就要判断该用户的状态,如是否为可用状态,如果不是可用状态该怎么提示等等,如果处于正常状态下,此时需要生成Session信息保存至服务器,这里我只保存了用户的状态,用户的Id以及用户的角色,为什么只保留这三个?
用户状态在用户操作中途可能产生变化,非管理员操作级别的状态变化,可不会对用户正常状态产生影响的;
用户Id永不变,唯一标识,故保存;
用户角色保存是本项目太多基于角色的需求,但是保存角色会引起的问题是,如果管理员对用户A修改了角色,这个时候A并不知道,他此时在数据库Session中还是原来角色,需要用户A重新登录才能生效,具体的解决办法需要商议,这里涉及到客户端的通知下发;
用户登录后,再次使用api的时候,会查阅其是否有使用该api的权限,这里检查肯定是读取缓存,而不是每次去数据库查某个角色所携带的所有可用API类目;

看,权限就做完了,你可能需要自己再去学下关于缓存的知识咯;
如果需要自制缓存管理,就要选用一个线程安全的数据结构来存储需要缓存的数据,初始化方法,对数据结构的各种操作,比如,先缓存数据库中所有用户的名字和id,此时,管理员添加了一个用户,那么这里的缓存数据中就要添加这么一个名字和id,所以,您得有这样得对外方法提供调用;
缓存数据管理,需要在服务供外之前做完初始化,所以,记得使用await;
对于,Controller层级,一定要多想到组合的方式完成整个流程,这是我重构第二版的时候才做到的【这里真的是万分有幸才有机会重构】,由于重构时间的关系,预想的IdentityServer4授权改为了现在设计的流程,Redis改为了自制的缓存形式,但是Controller层级所有组合都使用的async/await的方式,如果缓存改成redis,那么直接在组合的方法实现里把自制的改成redis的即可,不会影响太大!
感谢您看完这么多字,祝生活美好;
网友评论