diff --git a/website/docs/guide/plugins/auth.md b/website/docs/guide/plugins/auth.md new file mode 100644 index 000000000..7fc955e75 --- /dev/null +++ b/website/docs/guide/plugins/auth.md @@ -0,0 +1,212 @@ +--- +title: 权限管理 +order: 4 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +
+ 示例 + +
+ +对于一个 Web 应用,权限管理是经常会涉及的需求之一,通常包含以下几种常见的权限管理类型: + +- 页面权限:当用户访问某个没有权限的页面时跳转到无权限页面 +- 操作权限:页面中的某些按钮或组件针对无权限的用户直接隐藏 +- 接口权限:当用户通过操作调用没有权限的接口时跳转到无权限页面 + +icejs 提供 `@ice/plugin-auth` 插件,帮助用户更简单管理前两种类型的权限。接口权限管理请见数据请求文档。 + +## 安装插件 + +安装插件: + +```bash +$ npm i @ice/plugin-auth -D +``` + +在 `ice.config.mts` 中添加插件: + +```ts title="ice.config.mts" +import { defineConfig } from '@ice/app'; +import auth from '@ice/plugin-auth'; + +export default defineConfig({ + plugins: [ + auth(), + ], +}); +``` + +## 初始化权限数据 + +大多数情况下权限管理通常需要从服务端获取权限数据,然后在前端通过权限对比以此控制页面、操作等等权限行为。约定在 `src/app.ts` 中导出 `auth` 对象,该对象包含从服务端异步获取初始化的权限数据,并且约定最终返回格式为 `{ initialAuth: { [key: string]: boolean } }`。 + +```ts title="src/app.ts" +import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; + +export const auth = defineAuthConfig(async () => { + // 模拟请求权限数据 + // const data = (await fetch('/api/auth')).json(); + return { + initialAuth: { + admin: true, + guest: false, + }, + }; +}); +``` + +## 页面权限 + +如需对某些页面进行权限控制,只需在页面组件的 `getConfig` 中配置准入权限即可。 + + + + +```tsx +export default function Home() { + return
Home
+} + +export function getConfig() { + return { + // 当前用户是 admin 时,有权限访问该页面 + auth: ['admin'], + }; +} +``` + +
+ + +```tsx +export default function About() { + return
About
+} + +export function getConfig() { + return { + // 当前用户是 admin 时,无权限访问该页面 + auth: ['guest'], + }; +} +``` + +
+
+ +## 操作权限 + +在某些场景下,如某个组件中要根据角色判断是否有操作权限,我们可以通过 useAuth Hooks 在组件中获取权限数据,同时也可以更新初始的权限数据。 + +### 获取权限数据 + +```tsx +import React from 'react'; +import { useAuth } from 'ice'; + +function Foo() { + const [auth] = useAuth(); + return ( + <> + 当前用户权限数据: + {JSON.stringify(auth)} + + ); +} +``` + +### 设置权限数据 + +```tsx +import React from 'react'; +import { useAuth } from 'ice'; + +function Home() { + const [auth, setAuth] = useAuth(); + + // 更新权限,与默认的 auth 数据进行合并 + function updateAuth() { + setAuth({ admin: false, guest: true }); + } + + return ( + <> + 当前用户角色: + {JSON.stringify(auth)} + + + ); +} +``` + +### 自定义权限组件 + +对于操作类权限,通常我们可以自定义封装权限组件,以便更细粒度的控制权限和复用。 + +```tsx +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 { + // 无权限时显示指定 UI + return fallback || NoAuth; + } +} + +export default Auth; +``` + +使用如下: + +```tsx +function Foo() { + return ( + + + + ); +} +``` + +## 自定义 Fallback + +支持自定义无权限时的展示组件,默认为 `<>No Auth` + +```diff title="src/app.tsx" +import { defineAuthConfig } from '@ice/plugin-auth/esm/types'; + +export const auth = defineAuthConfig(async () => { + return { + initialAuth: { + admin: true, + }, ++ NoAuthFallback: (routeConfig) => { ++ console.log(routeConfig); // 当前页面的配置 ++ return ( ++
没有权限
++ ) ++ }, ++ }; +}); +```