Appearance
权限数据模型介绍
在项目中要进行权限控制,需要有一套权限相关的数据表来提供支持,这是整个权限控制的基础。本系统采用的权限数据模型是在经典的 RBAC 权限数据模型的基础之上进行的改进,共涉及到如下9张表:
- pd_core_org 组织表
- pd_core_station 岗位表
- pd_auth_user 用户表
- pd_auth_role 角色表
- pd_auth_resource 资源表
- pd_auth_menu 菜单表
- pd_auth_user_role 用户角色关系表
- pd_auth_role_authority 角色权限关系表
- pd_auth_role_org 角色组织关系表
需要说明的是,菜单和资源其实都属于权限,是两种不同类型的权限,即菜单权限和资源权限。具体说明如下:
- 菜单权限:对应的是系统的菜单,不同的用户可能拥有不同的菜单权限,登录系统后看到的菜单也不同
- 资源权限:对应的是某个功能的访问接口,拥有权限则可以访问此接口,没有权限则禁止访问此接口
表结构说明
在 MySQL 中创建 pd_auth 数据库
sql
CREATE DATABASE `pd_auth` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;在此数据库中执行 pinda-authority-project\document\sql 目录的 pd_auth.sql 脚本导入相关表格。执行完后可以看到如下11张表:
pd_common_login_log 表
pd_common_login_log 是用户登录日志表,具体的字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| request_ip | varchar | 操作IP |
| user_id | bigint | 登录人ID |
| user_name | varchar | 登录人姓名 |
| account | varchar | 登录人账号 |
| description | varchar | 登录描述 |
| login_date | date | 登录时间 |
| ua | varchar | 浏览器请求头 |
| browser | varchar | 浏览器名称 |
| browser_version | varchar | 浏览器版本 |
| operating_system | varchar | 操作系统 |
| location | varchar | 登录地点 |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
pd_common_opt_log 表
pd_common_opt_log 是用户操作日志表,具体字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| request_ip | varchar | 操作IP |
| type | varchar | 日志类型 OPT:操作类型 EX:异常类型 |
| user_name | varchar | 操作人 |
| description | varchar | 操作描述 |
| class_path | varchar | 类路径 |
| action_method | varchar | 请求方法 |
| request_uri | varchar | 请求地址 |
| http_method | varchar | 请求类型 GET/POST/PUT/DELETE/PATCH/TRACE/HEAD/OPTIONS |
| params | longtext | 请求参数 |
| result | longtext | 返回值 |
| ex_desc | longtext | 异常详情信息 |
| ex_detail | longtext | 异常描述 |
| start_time | timestamp | 开始时间 |
| finish_time | timestamp | 完成时间 |
| consuming_time | bigint | 消耗时间 |
| ua | varchar | 浏览器请求头 |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
pd_auth_menu 表
pd_auth_menu 是菜单表,具体字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| name | varchar | 菜单名称 |
| describe_ | varchar | 功能描述 |
| is_public | bit | 是否是公开菜单 |
| path | varchar | 对应路由path |
| component | varchar | 对应路由组件component |
| is_enable | bit | 是否启用 |
| sort_value | int | 排序 |
| icon | varchar | 菜单图标 |
| group_ | varchar | 菜单分组 |
| parent_id | bigint | 父级菜单id |
| create_user | bigint | 创建人id |
| create_time | datetime | 创建时间 |
| update_user | bigint | 更新人id |
| update_time | datetime | 更新时间 |
pd_auth_resource 表
pd_auth_resource 是资源表,具体字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| code | varchar | 资源编码 |
| name | varchar | 接口名称 |
| menu_id | bigint | 菜单ID |
| method | varchar | HTTP请求方式 |
| url | varchar | 接口请求url |
| describe_ | varchar | 接口描述 |
| create_user | bigint | 创建人id |
| create_time | datetime | 创建时间 |
| update_user | bigint | 更新人id |
| update_time | datetime | 更新时间 |
pd_auth_role 表
pd_auth_role 是角色表,具体字段如下:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| name | varchar | 角色名称 |
| code | varchar | 角色编码 |
| describe_ | varchar | 角色描述 |
| status | bit | 是否启用状态 |
| readonly | bit | 是否内置角色 |
| create_user | bigint | 创建人id |
| create_time | datetime | 创建时间 |
| update_user | bigint | 更新人id |
| update_time | datetime | 更新时间 |
pd_auth_user 表
pd_auth_user 是用户表,具体字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| account | varchar | 账号 |
| name | varchar | 姓名 |
| org_id | bigint | 组织ID |
| station_id | bigint | 岗位ID |
| varchar | 邮箱 | |
| mobile | varchar | 手机号 |
| sex | varchar | 性别 |
| status | bit | 启用状态 |
| avatar | varchar | 头像 |
| work_describe | varchar | 工作描述 |
| password_error_last_time | datetime | 最后一次输错密码时间 |
| password_error_num | int | 密码错误次数 |
| password_expire_time | datetime | 密码过期时间 |
| password | varchar | 密码 |
| last_login_time | datetime | 最后登录时间 |
| create_user | bigint | 创建人id |
| create_time | datetime | 创建时间 |
| update_user | bigint | 更新人id |
| update_time | datetime | 更新时间 |
pd_core_station 表
pd_core_station 是岗位表,具体字段如下:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| name | varchar | 岗位名称 |
| org_id | bigint | 组织ID |
| status | bit | 是否启用状态 |
| describe_ | varchar | 描述 |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
| update_time | datetime | 更新时间 |
| update_user | bigint | 更新人ID |
pd_core_org 表
pd_core_org 是组织表,具体字段如下:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| name | varchar | 组织名称 |
| abbreviation | varchar | 简称 |
| parent_id | bigint | 父ID |
| tree_path | varchar | 树结构 |
| sort_value | int | 排序 |
| status | bit | 状态 |
| describe_ | varchar | 描述 |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
| update_time | datetime | 更新时间 |
| update_user | bigint | 更新人ID |
pd_auth_user_role 表
pd_auth_user_role 是用户角色关系表,具体字段为:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| role_id | bigint | 角色ID |
| user_id | bigint | 用户ID |
| create_user | bigint | 创建人ID |
| create_time | datetime | 创建时间 |
pd_auth_role_org 表
pd_auth_role_org 是角色组织关系表,具体字段为:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| role_id | bigint | 角色ID |
| org_id | bigint | 组织ID |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
pd_auth_role_authority 表
pd_auth_role_authority 是角色权限关系表,具体字段为:
| 字段名称 | 类型 | 说明 |
|---|---|---|
| id | bigint | 主键 |
| authority_id | bigint | 权限ID |
| authority_type | varchar | 权限类型 MENU:菜单 RESOURCE:资源 |
| role_id | bigint | 角色ID |
| create_time | datetime | 创建时间 |
| create_user | bigint | 创建人ID |
导入实体类
以上介绍了通用权限系统中涉及到的数据表,一般在开发过程中会创建和数据表对应的实体类来封装相关信息。此部分相关实体类 Entity 和相关 DTO,直接准备好放到 pd-auth-entity 工程中
认证和鉴权流程
品达通用权限系统对外提供的功能中认证和鉴权是其核心功能,通过导入的初始工程可以发现其中有两个服务,即网关服务和权限服务。其中用户认证需要在权限服务中完成,鉴权需要在网关服务中完成。在实现此两个核心功能之前,必须明确认证和鉴权的整体执行流程。
认证流程
- 用户通过前端系统发送登录请求,请求中携带账号、密码、验证码等信息。
- 前端登录请求首先请求到网关服务,网关服务将请求路由到权限微服务。
- 权限微服务进行认证操作,如果认证通过则生成 jwt token 返回给前端,同时将用户拥有的资源权限使用 userId 作为 key 保存到缓存中。
Notes: 缓存中保存的用户资源权限是由 pd_auth_resource 资源表中的 method 和 url 两个字段的值拼接成的。例如,某个用户拥有删除日志的权限,在表中删除日志权限对应一条数据,其中 method 的值为 DELETE,url 的值为
/optLog,那么缓存中保存的用户拥有的资源权限为:DELETE/optLog。
鉴权流程
- 用户认证后访问其他功能时将 jwt token 放在请求头中,首先经过网关服务处理。
- 在网关服务的过滤器中获取请求头中的 token 并进行解析,将解析出的用户相关数据放在 zuul 的 header 中。
Notes: 之所以要将用户相关数据放在zuul的header中,是因为在后续的网关AccessFilter过滤器和权限服务中都会使用到这些数据。
- 在网关服务的过滤器中进行鉴权相关处理。