一、前言
之前的博客,介绍了Java后端开发基础环境的搭建,SpringBoot的打包,jenkins自动化部署,项目docker容器化。从本期开始,将正式开始探究SpringBoot开发中的一些问题。
之前的博客代码,搭建了基础的SpringBoot开发框架。为了简便起见,忽略了很多重要的问题。其中最为重要的就是鉴权操作。我之前的《芝法酱躺平攻略》系列,也讲过鉴权相关内容。不过那时写的有些不落实际。那时的设计,认为存在一个部门的树级结构,所有项目中的资源与这个树级结构的结点绑定,用户也与该树级结构的节点绑定。用户只能访问所在树节点下该节点和子孙节点绑定的资源。这样的设计看似很通用,然而在实际的项目中,不但过于复杂,并且不贴近实际需求。
实际的项目中,鉴权逻辑通常基于角色,角色绑定在用户上。所以那套复杂的鉴权逻辑也根本不适用。
本节仅仅总览式的介绍本大章的目标和设计,具体细节在后面的小节一一介绍。
二、鉴权相关的需求分析
2.1 目标分析
- 登录注册的功能
我们本次博客,沿用《芝法酱躺平攻略》系列的相关技术,用户的密文以加密形式存储数据库。但毕竟是学习贴,客户端的用户名和密码就不做加解密处理了,未来介绍到前端技术时再补上。 - 令牌访问接口的功能
用户成功登录后,后端返回jwt密钥,前端拿到该密钥访问后端接口。
本次博客打算做一下技术升级,jwt密钥直接在nginx端解析,如果验证不通过直接返回前端错误。
验证通过后,把jwt中payload的附带信息解析出来,转成base64放到header特定字段中,发给后端服务。 - 分服功能
jwt中附带分配给用户是哪个服务,在nginx中解析后,路由到对应的服务中去。实际进销存的项目,为了便于调试和客户版本管理,通常不会随机分服,而是把客户企业所属的服务器放在企业表字段中。 - 鉴权功能
写一个拦截器,如果接收到nginx发来的相应权限信息,解析到一个ThreadLocal中,可以通过注入TokenUtil的方式,在代码的各个地方轻松的获取权限信息。
当然,还会有RequireRole等注解,要求用户拥有某个角色权限,才能访问特定接口。 - 根据用户所在企业自动切库
我们设定,每个用户有企业属性,所有资源都绑定了企业字段。不同企业可能放到不同的数据库中。用这种方式,缓解数据库的压力。通过AOP自动切库。 - 多数据源与事务的支持
我们会将数据库分成这两种,监控中心库和企业中心库。
监控中心库存放用户账户相关的信息,所有用户的数据都存在这个库中。
企业中心库存放用户企业的业务数据,企业中心库会有多个库,在用户注册企业时,分配其所属的库。
我们需要让SpringBoot的Transactional注解,支持多数据源。一个数据源的操作发生错误,所有数据源一起回滚。由于本章的技术栈,还没有讲到微服务,并且进销存管理系统的需求,其实也用不到微服务。我们需要寻找单体服务的解决方案。即不会使用阿里的seata框架,因为该框架额外的引入了一个事务管理的微服务,增加了系统的复杂度。 - 自动填充
对于业务数据,诸如create_by_id等审计字段自不用说,还会自动填充企业Id和企业Code,减少业务开发时的重复操作。 - 数据域鉴权
在mapper上加特定注解,使得执行sql时,在where子句中自动附加一些鉴权相关语句,同时支持mybatis和mybatis-plus。考虑到报表可能用原生mybatis开发,存在子查询等情况,可以在xml中添加$Auth等特殊符号,在执行时自动替换相应鉴权语句。
这样做的好处是,让鉴权与业务开发分离,使代码更加清晰。同时鉴权需求改变时,不需要变更业务代码。 - 封装
我们会把许多共通的代码封装到zhi-fa-engine的项目中,业务项目直接通过pom引用,减少开发人员负担。共通代码除了上面提到的需求外,还会增加诸如redis等常用功能的支持
2.2 业务设计
还是接着之前的供应商管理系统来做。但我们会做更多细化,让他更接近真实项目的需求。
我们核心的需求是,销售员身上绑定有不同片区的code,表示其所管辖的片区。销售员只能去所管辖片区下的门店进行销售。销售单查询时,也只能查询到管辖片区下的销售单。
2.2.1 企业概念
每个用户有一个所属企业,用户只能看到该企业下的数据。
2.2.2 门店概念
本系统的销售报表,都是批发商向门店销售。每一个单据都绑定有门店Id。
2.2.3 区域概念
用户上绑定有若干个片区,该用户只能查看所属这些片区的门店的相关业务。
2.2.4 角色概念
一些接口,需要要求用户拥有某个角色,才可访问
2.3 服务架构
2.4 数据库设计
2.4.1 库分配
本次用3个库模拟:
monitor库,放置用户表、企业表和数据库描述表
busy001,busy002分别是2个业务库
2.4.2 新表的设计
之前的业务表,每张表添加enp_code
monitor库
定义模块
监控中心
三、代码展示
还是移步码云
本次目标比较大,为降低写文章成本,我就把本大章的代码全开发完放一起了。代码没完全写完,我会不断补充。
到这一章,难度已经进入中级开发,对于在校生和应届生同学,学习起来会有一定难度。