權限管理
項目中經常有的場景是不同的用戶的權限不同。
- 不同的用戶在頁面中可以看到的元素和操作不同(控制元素顯示和操作按鈕)
- 不同的用戶對頁面的訪問權限不同(控制路由菜單)
頁面權限跟頁面菜單 id 綁定。獲取當前頁面id后,找到對應的頁面權限,控制頁面按鈕或者模塊的顯示隱藏。后端同步控制校驗對應請求路由的權限。
菜單管理 (只是維護信息)
菜單綁定:頁面元素和頁面操作
頁面元素:【元素標志】【元素名稱】【操作->控制當前頁面元素數據記錄的增刪改查】
頁面操作:【操作標志】【操作名稱】【API】
權限管理 (給角色授權菜單、操作、顯示權限)
勾選菜單:給當前用戶賦予可以展示的菜單
勾選操作:在有權限的菜單下勾選操作和顯示權限
授予角色
權限基礎信息維護好后,給用戶授予角色(權限組)
Vue 可以基於全局指令來實現
Raect 可以基於 umi.js access 插件
// src/access.ts
export default function(initialState) {
const { userId, role, isAdmin, hasRoutes = [] } = initialState; // 后端維護和組織好權限數據
// 返回一個權限對象、每一個key對應一個布爾值(一個操作權限)
return {
canReadFoo: true,
canUpdateFoo: role === 'admin',
canDeleteFoo: foo => {
return foo.ownerId === userId;
},
adminRouteFilter: () => isAdmin, // 只有管理員可訪問
normalRouteFilter: (route) => hasRoutes.includes(route.name), // initialState 中包含了的路由才有權限訪問
};
}
路由和菜單的權限控制
routes: [ { path: '/foo', name: 'foo', // ... access: 'normalRouteFilter', // 會調用 src/access.ts 中返回的 normalRouteFilter 進行鑒權 }, { path: '/admin', name: 'admin', // ... access: 'adminRouteFilter', // 會調用 src/access.ts 中返回的 adminRouteFilter 進行鑒權 }, ]
頁面內的權限控制
import React from 'react'; import { useAccess, Access } from 'umi'; const PageA = (props) => { const { foo } = props; const access = useAccess(); // access 實例的成員: canReadFoo, canUpdateFoo, canDeleteFoo if (access.canReadFoo) { // 任意操作 } return ( <div> <Access accessible={access.canReadFoo} fallback={<div>Can not read foo content.</div>}> Foo content. </Access> <Access accessible={access.canUpdateFoo()} fallback={<div>Can not update foo.</div>}> Update foo. </Access> <Access accessible={access.canDeleteFoo(foo)} fallback={<div>Can not delete foo.</div>}> Delete foo. </Access> </div> ); };