权限管理系统开发
前言
权限管理是一个企业级项目的底座,必不可少,我想通过一个具体项目,系统学习一下权限管理模块的开发。
RBAC
RBAC(Role-Based Access Control): 基于角色的访问控制,它通过角色这一中间层来管理权限。
用户(User) → 角色(Role) → 权限(Permission) → 资源(Resource)
数据库连接池
由于每次查询或者操作数据库时,都需要先建立tcp连接、身份认证、数据库初始会话等操作,开销很大,所以建立一个中间层,也就是连接池。
以后每次的工作流程:
请求到来
↓
从连接池获取一个空闲连接
↓
执行 SQL
↓
连接归还连接池
连接池主要解决三个问题:
- 减少建连开销
- 限制数据库连接数量
- 复用已有连接,提高并发性能
1 | db, err := sql.Open("mysql", dsn) |
日志系统
日志系统是一个系统必不可少的东西,它负责记录应用程序的运行状态、错误信息和操作日志。本项目使用Zap作为日志库,配合Lumberjack实现日志轮转功能,提供了高性能的日志记录能力。
用一个logger.go文件来配置日志系统,我发现这些数据库啊,日志啊,这些都是简单的用一个文件就搞定了,里面一般先写个Init函数,在被其它包导入时自动执行,也就是日志系统自己的配置操作,例如配置日志轮转、编码器、设置级别、创建core(日志运转逻辑核心),然后写日志系统能够向外提供的函数,如Info记录日志信息(张三登录,登陆成功,张三进入管理界面等),然后Error记录报错信息。
权限管理
权限管理模块基于Casbin实现RBAC(基于角色的访问控制)权限系统,提供了灵活的权限控制能力。Casbin是一个权限控制框架,支持多种访问控制模型,主要用于判断:
谁,能不能在某个界面,执行某个操作,能就返回True
它与RBAC模型配合工作
数据模型
也就是各种medel,主要就是定义结构体及json字段映射,有些还要在里面写开放函数。
用户认证
用户认证模块基于JWT(JSON Web Token)实现无状态的用户认证机制。
JWT包含用户信息,无需在服务器端存储会话状态。
由三部分组成,用户信息主要放在第二部分(payload),例如用户id,签名时间、生效时间、过期时间等。它最终返回一个有有效期的token,文件中还写了验证jwt token的函数。
数据访问层
基础仓库
由于每个模型都有自己的仓库,所以设置一个基础仓库,提供基础的CRUD,减少代码耦合。
基础仓库提供了通用的数据访问操作,使用泛型设计,为所有业务模型提供统一的CRUD操作接口。通过继承基础仓库,可以快速实现各种业务模型的数据访问层。
业务层调用仓库层
比如用户服务,这个服务中是需要调用多张表的,每张表对应一个仓库(用户仓库,角色仓库,权限仓库),每个仓库对外暴漏自己的接口,也就是说用户服务是集成了各个仓库的接口的,所以用户服务可以通过每个仓库的接口来对每个仓库进行操作。毕竟各个仓库的接口也集成了仓库的CRUD等操作。
所以有一天你想把 MySQL 换成 PostgreSQL,只需重写一个 postgresUserRepository,Service 层一行代码不用改 — 因为 Service 只认 UserRepository 接口,不认具体实现
中间件
如jwt验证流程、跨域放行、权限检查、日志
对于一个参数c *gin.Context
c *gin.Context是每个请求一个独立的c,而不是全局唯一一个c。
请求到达
↓
Gin 创建 c (属于张三的这个请求)
↓
Logger(c) ← 同一个 c
↓
Cors(c) ← 同一个 c
↓
JWTAuth(c) ← 同一个 c,往 c 里 Set(“user_id”, 1)
↓
GetUsers(c) ← 同一个 c,能 Get(“user_id”) 取到 1
↓
Success(c, …) ← 同一个 c
API处理层(handler)
也就是处理请求的,错误了要返回错误码;参数c就是在这里创建的
路由配置
写初始化函数,包括所有handlers和所有routes
main函数
完成所有的初始化,启动服务器,并添加一个健康检查接口。
健康检查接口就是服务的”心跳”——启动后浏览器/curl 访问一下 localhost:8080/health,返回 {"status":"ok"} 就说明服务正常运行。

