2023-02-26 14:18:22 +08:00
|
|
|
|
## 权限控制
|
|
|
|
|
|
|
|
|
|
目录
|
|
|
|
|
|
|
|
|
|
- 一、菜单权限
|
|
|
|
|
- 二、数据权限
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 一、菜单权限
|
|
|
|
|
|
|
|
|
|
> 菜单权限可以控制web后台菜单功能,每个菜单可以绑定一个或多个API权限,API权限决定了用户是否可以调用服务端接口。
|
|
|
|
|
|
|
|
|
|
#### 为角色添加菜单权限
|
|
|
|
|
|
|
|
|
|
1、HotGo后台 -> 权限管理 -> 菜单权限 -> 找到添加菜单,按照表单提示添加你的菜单信息。
|
|
|
|
|
|
|
|
|
|
2、添加菜单完成后,到 权限管理 -> 角色权限 -> 找到一位已有角色或者添加新角色 -> 在列表右侧操作栏找到菜单权限打开 -> 将第1步中添加的菜单分配给该角色即可。
|
|
|
|
|
|
|
|
|
|
#### 细粒度权限
|
|
|
|
|
|
|
|
|
|
> 一般用于web后台页面上的功能按钮,对不同的角色展示不同的按钮时会用到。
|
|
|
|
|
|
|
|
|
|
1、参考【为角色添加菜单权限】添加一个按钮类型的菜单。并为菜单分配API权限,假设你分配权限是:/test/index
|
|
|
|
|
|
|
|
|
|
2、在web页面中创建一个按钮,如下:
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
<template>
|
|
|
|
|
<div>
|
|
|
|
|
<n-button v-if="hasPermission(['/test/index'])">拥有[/test/index]权限可见</n-button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
|
import { usePermission } from '@/hooks/web/usePermission';
|
|
|
|
|
const { hasPermission } = usePermission();
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 菜单表主要字段解释
|
|
|
|
|
|
|
|
|
|
- 代码片段:[server/internal/model/input/adminin/menu.go](../../server/internal/model/input/adminin/menu.go)
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
type MenuRouteMeta struct {
|
|
|
|
|
// 解释参考:https://naive-ui-admin-docs.vercel.app/guide/router.html#%E5%A4%9A%E7%BA%A7%E8%B7%AF%E7%94%B1
|
|
|
|
|
Title string `json:"title"` // 菜单名称 一般必填
|
2023-07-24 09:35:30 +08:00
|
|
|
|
// Disabled bool `json:"disabled,omitempty"` // 禁用菜单
|
2023-02-26 14:18:22 +08:00
|
|
|
|
Icon string `json:"icon,omitempty"` // 菜单图标
|
|
|
|
|
KeepAlive bool `json:"keepAlive,omitempty"` // 缓存该路由
|
|
|
|
|
Hidden bool `json:"hidden,omitempty"` // 隐藏菜单
|
|
|
|
|
Sort int `json:"sort,omitempty"` // 排序越小越排前
|
|
|
|
|
AlwaysShow bool `json:"alwaysShow,omitempty"` // 取消自动计算根路由模式
|
|
|
|
|
ActiveMenu string `json:"activeMenu,omitempty"` // 当路由设置了该属性,则会高亮相对应的侧边栏。
|
|
|
|
|
// 这在某些场景非常有用,比如:一个列表页路由为:/list/basic-list
|
|
|
|
|
// 点击进入详情页,这时候路由为/list/basic-info/1,但你想在侧边栏高亮列表的路由,就可以进行如下设置
|
|
|
|
|
// 注意是配置高亮路由 `name`,不是path
|
|
|
|
|
IsRoot bool `json:"isRoot,omitempty"` // 是否跟路由 顶部混合菜单,必须传 true,否则左侧会显示异常(场景就是,分割菜单之后,当一级菜单没有子菜单)
|
|
|
|
|
FrameSrc string `json:"frameSrc,omitempty" ` // 内联外部地址
|
|
|
|
|
Permissions string `json:"permissions,omitempty"` // 菜单包含权限集合,满足其中一个就会显示
|
|
|
|
|
Affix bool `json:"affix,omitempty"` // 是否固定 设置为 true 之后 多页签不可删除
|
|
|
|
|
Type int `json:"type"` // 菜单类型
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### API权限验证流程
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
|
|
|
|
graph TD
|
|
|
|
|
A(用户请求API) --> B(验证中间件<br> server/internal/logic/middleware/admin_auth.go)
|
|
|
|
|
B -->|没有登录,但API需要登录| H(提示登录)
|
|
|
|
|
B -->|没有登录,但API不需要登录| G(验证通过,进入业务)
|
|
|
|
|
B -->|已登录| C(检查用户角色是否拥有API权限<br> server/internal/logic/admin/role.go,方法:Verify) -->|有权限| G(验证通过,进入业务)
|
|
|
|
|
C -->|API无需验证权限| G(验证通过,进入业务流程)
|
|
|
|
|
C -->|无权限| D(提示无权限)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 菜单权限添加或修改后多久生效?
|
|
|
|
|
|
|
|
|
|
- API权限实时生效,web后台菜单刷新页面后生效,无需重启服务
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 二、数据权限
|
|
|
|
|
|
|
|
|
|
> 数据权限是某人只能看到某些数据,可以为某人设置一定的数据范围,让其只能看到允许他看到的数据。
|
|
|
|
|
|
|
|
|
|
> 例如:公司存在多个销售部门,不同的部门仅能查看到自己所属部门下的数据;再如:用户有多级代理商,只能查看自己和自己下级的数据。
|
|
|
|
|
|
|
|
|
|
#### 目前已经支持的数据权限如下
|
|
|
|
|
|
|
|
|
|
| 数据范围 | 描述 |
|
|
|
|
|
|---------|--------------------------------------------|
|
|
|
|
|
| 全部权限 | 不做过滤,可以查看所有数据 |
|
|
|
|
|
| 当前部门 | 仅可以看到所属部门下的数据 |
|
|
|
|
|
| 当前以及下部门 | 仅可以看到所属以及下级部门的数据 |
|
|
|
|
|
| 自定义部门 | 可以看到设置的指定部门,支持多个 |
|
|
|
|
|
| 仅自己 | 仅可以看到自己的数据 |
|
|
|
|
|
| 自己和直属下级 | 仅可以看到自己和直属下级的数据,直属下级是指当前用户往下1级的用户 |
|
|
|
|
|
| 自己和全部下级 | 仅可以看到自己和全部下级的数据,全部下级是指当前用户所有的下级用户,包含其下级的下级 |
|
|
|
|
|
|
|
|
|
|
#### 如何区分部门和下级用户?
|
|
|
|
|
|
|
|
|
|
- 在实际使用时,部门更多的是在公司或机构中使用,可以通过在 组织管理 -> 后台用户 ->为用户绑定部门
|
2024-03-07 20:08:56 +08:00
|
|
|
|
- 下级用户在代理商或分销系统中比较常见,后台用户由谁添加的,那么被添加的用户就是其下级用户
|
2023-02-26 14:18:22 +08:00
|
|
|
|
|
|
|
|
|
#### 如何判断数据是谁的?
|
|
|
|
|
|
|
|
|
|
- 在数据库建表时,只要表中包含字段:`created_by`或`member_id`即可过滤 [仅自己、自己和直属下级、自己和全部下级] 类型的数据权限
|
|
|
|
|
|
|
|
|
|
#### 如何在具体业务中使用数据权限过滤?
|
|
|
|
|
|
|
|
|
|
- 只需在查询、更新或删除等ORM链式操作中加入相应`Handler`方法即可
|
|
|
|
|
|
|
|
|
|
- 如果你想对Handler有更多详细了解,请查看:https://goframe.org/pages/viewpage.action?pageId=20087340
|
|
|
|
|
|
|
|
|
|
- 下面提供一个简单使用例子:
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"hotgo/internal/dao"
|
|
|
|
|
"hotgo/internal/library/hgorm/handler"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func test(ctx context.Context) {
|
|
|
|
|
dao.AdminPost.Ctx(ctx).Where("id", 1).Handler(handler.FilterAuth).Scan(&res)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- 如果表中没有字段:`created_by`或`member_id`,也可以使用自定义字段方法来过滤数据权限,如下:
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"hotgo/internal/dao"
|
|
|
|
|
"hotgo/internal/library/hgorm/handler"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func test(ctx context.Context) {
|
|
|
|
|
dao.AdminPost.Ctx(ctx).Where("id", 1).Handler(handler.FilterAuthWithField("test_field")).Scan(&res)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 过滤方法实现请参考:[server/internal/library/hgorm/handler/filter_auth.go](../../server/internal/library/hgorm/handler/filter_auth.go)
|
|
|
|
|
|
|
|
|
|
|