对于一个 Web 应用,权限管理是经常会涉及的需求之一,通常包含以下几种常见的权限管理类型:
- 页面权限:当用户访问某个没有权限的页面时跳转到无权限页面;
- 操作权限:页面中的某些按钮或组件针对无权限的用户直接隐藏;
- 接口权限:当用户通过操作调用没有权限的接口时跳转到无权限页面。
初始化权限数据
大多数情况下权限管理通常需要从服务端获取权限数据,然后在前端通过权限对比以此控制页面、操作等等权限行为。在 icejs 框架中约定通过 app.getInitialData() 从服务端异步获取初始化的权限数据,并且约定最终返回格式为 {auth: {[key: string]: boolean }} 的形式。
import { runApp, request, IAppConfig } from 'ice';const appConfig: IAppConfig = {app: {getInitialData: async () => {// 模拟服务端返回的数据const data = await request('/api/auth');const { role, starPermission, followPermission } = data;// 约定权限必须返回一个 auth 对象// 返回的每个值对应一条权限return {auth: {admin: role === 'admin',guest: role === 'guest',starRepo: starPermission,followRepo: followPermission,},};},},auth: {// 可选的,设置无权限时的展示组件,默认为 nullNoAuthFallback: <div>没有权限...</div>,// 或者传递一个函数组件// NoAuthFallback: () => <div>没有权限..</div>},};runApp(appConfig);
页面权限
页面权限通常也称之为路由权限,如需对某些页面进行权限控制只需在页面组件的 pageConfig 中配置准入权限即可。
// src/routes.tsimport Home from '@/pages/Home';export default [{path: '/home',component: Home,+ // 注意:仅 2.x 支持,icejs 1.x 只支持将 pageConfig 配置在对应的页面组件上,请参考「页面组件」章节+ pageConfig: {+ auth: ['admin'],+ },},];export default routerConfig;
操作权限
在某些场景下,如某个组件中要根据角色判断是否有操作权限,我们可以通过 useAuth Hooks 在组件中获取权限数据,同时也可以更新初始的权限数据。
获取权限数据
import React from 'react';import { useAuth } from 'ice';function Foo() {const [auth] = useAuth();return (<>当前用户权限数据:<code>{JSON.stringify(auth)}</code></>);}
设置权限数据
import React from 'react';import { useAuth } from 'ice';function Foo() {const [auth, setAuth] = useAuth();// 更新权限,与默认的 auth 数据进行合并function updateAuth() {setAuth({ starRepo: false, followRepo: false });}return (<>当前用户角色:<code>{JSON.stringify(auth)}</code><button type="button" onClick={updateAuth}>更新权限</button></>);}
自定义权限组件
对于操作类权限,通常我们可以自定义封装权限组件,以便更细粒度的控制权限和复用。
import React from 'react';import { useAuth } from 'ice';import NoAuth from '@/components/NoAuth';function Auth({ children, authKey, fallback }) {const [auth] = useAuth();// 判断是否有权限const hasAuth = auth[authKey];// 有权限时直接渲染内容if (hasAuth) {return children;} else {// 无权限时显示指定 UIreturn fallback || NoAuth;}}export default Auth;
使用如下:
function Foo() {return (<Auth authKey={'starRepo'}><Button type="button">Star</Button></Auth>);}
接口鉴权
请参考文档 数据请求,业务上封装统一的请求方法,与服务端约定接口协议,前端根据状态码判断无权限、未登录等状态,然后跳转到指定页面。
版本升级
不再依赖状态管理方案
icejs 2.0 开始,auth 直接基于 Context 实现,不再依赖状态管理方案,开发者使用方式保持一致。
插件内置
icejs 1.11.2 开始框架默认内置权限插件,开发者无需安装。如果 ice.js 版本低于 1.11.2,需要自行安装 build-plugin-ice-auth 依赖,并在 build.json 中引入该插件。
