平台权限管理前端设计
用户登录流程
用户认证
平台使用 JWT(JSON Web Token) 进行用户认证,客户端通过登录接口获取 JWT 并保存,在访问接口数据时,需要携带 JWT,将 JWT 放在请求的 Authorization
头部。例如:
登录
import axios from 'axios';
var url = 'http://10.7.55.191:8000/api/token/';
var formData = new FormData();
formData.append('username', 'admin');
formData.append('password', '123456');
axios.post(url, formData).then(res=>{
setStorage("token", res.data.data.access);
setStorage("refresh", res.data.data.refresh);
})
访问数据
import axios from "axios";
var url = 'http://10.7.55.191:8000/api/version/';
var token = getStorage("token");
var headers = {
Authorization: "JWT " + token,
},
axios.get(url, {headers: headers})
上面用到的两个函数
setStorage
和getStorage
, 分别是保存和读取存储中的数据,具体会根据前端环境去实现。例如当前我们将用户数据保存在浏览器的localStorage
中:
export function setStorage(key, value) { window.localStorage.setItem(key, JSON.stringify(value)) }
export function getStorage(key) { return JSON.parse(window.localStorage.getItem(key)) }
JWT 的详细设计可以参考 官方文档。
当 access token 过期时,客户端可以通过 refresh token 刷新 access token。
http://10.7.55.191:8000/api/ 使我们的开发 API 地址
用户资源
登录后,客户端会开始获取用户资源,包括:
- 菜单列表及菜单中的按钮权限
- 用户角色、用户部门
研测平台的策略是仅显示用户有权限访问的菜单和对应的按钮。
研测平台的权限设计
研测平台前端的权限主体是角色,例如【管理员】、【测试】,客体是菜单和按钮,例如【新建】、【删除】。
对应的后端权限的客体是 接口 + 方法,前端的每个按钮与之对应。这种对应关系由管理员用户维护,即【系统管理】->【菜单管理】中的【按钮配置】功能。
一般来说前端菜单对应后端不同的接口,按钮对应接口的不同操作(GET,PUT,POST,PATCH,DELETE),但研测平台的不同的菜单可能对应后端同一个接口,不同的按钮也可能对应不同的接口。例如:
- 【版本测试】和【系统测试】其实是同一个后端接口实现的,但是有不同的前端菜单;
- 同一个任务页面【启动】按钮和【新建】按钮对应的不同的后端接口。
因此前端的权限还需要按照菜单区分,例如菜单A和菜单B都使用接口A,但是角色A和角色B需要对菜单A和菜单B有不同的权限,可以看到【按钮配置】是在对不同的菜单进行配置的。
研测平台前端通过权限确认是否显示某个菜单或按钮。例如下面是控制按钮显示的函数:
function isShowBtn(url, moduleName, btnName) {
/*
url: 前端路由
moduleName: 菜单名称
btnName: 按钮,即 http://10.7.13.132:8081/#/buttonManage 下的按钮的 Key
*/
if (getStorage("is_superuser") == "true") {
return true;
}
let btnArr = getStorage("menuList") ? JSON.parse(getStorage("menuList")) : [];
let isshow = false;
for (var i = 0; i < btnArr.length; i++) {
let item = btnArr[i];
if (
item.url == url &&
item.moduleName == moduleName &&
item.menuPermission &&
item.menuPermission.includes(btnName)
) {
isshow = true;
break;
}
}
return isshow;
}
权限主体和客体的关联即【权限配置】由管理员在【系统管理】-> 【权限管理】中维护。
研测平台的伪权限
伪权限是前端自己实现的权限,例如:用户作为权限主体(即每个用户有专属的权限)。
在机器的占用和释放中,需要对单个用户做权限控制。这里则由机器的用户名属性来控制,平台会判断当前用户是否该机器的占用用户来实现伪权限。下面是一个控制伪权限的函数:
export function hasPerm(pm) {
return getStorage("userId") === pm.user || getStorage("is_superuser") == 'true'
}
getStorage
是获取存储数据的函数。我们在登录的时候,通过setStorage
将uiserId
保存在浏览器中。