com-angel-authorization
com-angel-authorization
框架无关的用户权限配置 npm 包,可在 React 与 Vue 3 项目中使用。
特性
- 核心层与 UI 框架解耦,也可直接在非前端环境使用
- 支持权限码(permission)与角色(role)
any/all匹配模式- 超级管理员旁路(
isSuperAdmin) - React:
Provider+ Hooks +<Can> - Vue 3:Plugin + Composables +
v-permission+<Can>
本地预览
npm install
npm run demo
浏览器会打开 http://localhost:5173,可体验权限点管理的增删改查(Mock 数据,无需后端)。
安装
npm install com-angel-authorization
# 或
pnpm add com-angel-authorization
按需安装 peer 依赖:
# React 项目
npm install react
# Vue 项目
npm install vue
包入口
| 入口 | 用途 |
|---|---|
com-angel-authorization |
框架无关核心 |
com-angel-authorization/react |
React 适配 |
com-angel-authorization/vue |
Vue 3 适配 |
核心 API(框架无关)
import { createPermissionStore } from 'com-angel-authorization';
const store = createPermissionStore({
permissions: ['user:view', 'user:edit'],
roles: ['editor'],
isSuperAdmin: false,
});
store.hasPermission('user:edit'); // true
store.hasPermission(['user:edit', 'user:delete'], { mode: 'all' }); // false
store.hasRole('editor'); // true
store.can('user:view'); // true(hasPermission 别名)
// 登录后写入
store.hydrate({
permissions: ['user:view', 'user:edit', 'user:delete'],
roles: ['admin'],
});
// 登出清空
store.clear();
React 用法
import {
PermissionProvider,
usePermission,
useHasPermission,
Can,
} from 'com-angel-authorization/react';
function App() {
return (
<PermissionProvider
initialState={{
permissions: ['user:view', 'user:edit'],
roles: ['editor'],
}}
>
<Dashboard />
</PermissionProvider>
);
}
function Dashboard() {
const { can, hydrate, clear } = usePermission();
const canEdit = useHasPermission('user:edit');
// 登录成功后
// hydrate({ permissions: data.perms, roles: data.roles });
// 登出
// clear();
return (
<div>
{canEdit && <button>编辑</button>}
<Can permission="user:delete" fallback={<span>无删除权限</span>}>
<button>删除</button>
</Can>
<Can permission={['user:edit', 'user:delete']} mode="all">
<AdminTools />
</Can>
<Can role="admin" permission="user:edit" combine="or">
<button>管理入口</button>
</Can>
{can('user:view') && <UserList />}
</div>
);
}
也可传入外部 store,便于跨树或与路由守卫共享:
import { createPermissionStore } from 'com-angel-authorization';
import { PermissionProvider } from 'com-angel-authorization/react';
export const permissionStore = createPermissionStore();
<PermissionProvider store={permissionStore}>
<App />
</PermissionProvider>
Vue 3 用法
安装插件
import { createApp } from 'vue';
import { createPermissionPlugin, Can } from 'com-angel-authorization/vue';
import App from './App.vue';
const permission = createPermissionPlugin({
initialState: {
permissions: ['user:view', 'user:edit'],
roles: ['editor'],
},
});
const app = createApp(App);
app.use(permission);
app.component('Can', Can); // 可选:全局注册
app.mount('#app');
// 需要时在模块外访问
// permission.store.hydrate({ ... })
Composition API
<script setup lang="ts">
import { usePermission, useHasPermission, Can } from 'com-angel-authorization/vue';
const { can, hydrate, clear } = usePermission();
const canEdit = useHasPermission('user:edit');
async function onLogin() {
const data = await fetchUserAuth();
hydrate({
permissions: data.permissions,
roles: data.roles,
isSuperAdmin: data.isSuperAdmin,
});
}
</script>
<template>
<button v-if="canEdit">编辑</button>
<Can permission="user:delete">
<button>删除</button>
<template #fallback>无删除权限</template>
</Can>
<!-- 指令:无权限时隐藏元素 -->
<button v-permission="'user:edit'">编辑</button>
<button v-permission:all="['user:edit', 'user:delete']">危险操作</button>
<button v-permission:role="'admin'">管理员</button>
<button
v-permission="{
permission: 'user:edit',
role: 'admin',
combine: 'or',
}"
>
管理入口
</button>
</template>
选项式 / 模板全局方法
插件安装后可用:
<template>
<button v-if="$can('user:edit')">编辑</button>
<button v-if="$hasRole('admin')">管理</button>
</template>
API 速查
PermissionStore
| 方法 | 说明 |
|---|---|
hydrate(state) |
一次性写入权限 / 角色 / 超管 |
setPermissions(list) |
设置权限码 |
setRoles(list) |
设置角色 |
setSuperAdmin(bool) |
设置超管 |
clear() |
清空 |
hasPermission(codes, { mode }) |
校验权限,mode: any | all |
hasRole(codes, { mode }) |
校验角色 |
can(codes, options) |
hasPermission 别名 |
subscribe(listener) |
订阅变更,返回取消函数 |
getState() |
获取当前快照 |
<Can> 组件(React / Vue)
| Prop | 说明 |
|---|---|
permission |
权限码或数组 |
role |
角色码或数组 |
mode |
any(默认)/ all |
combine |
同时传 permission 与 role 时:and(默认)/ or |
fallback |
React:无权限占位;Vue:使用 #fallback 插槽 |
权限点管理(CRUD)
对接后端 /authorization-resources,提供列表 / 新增 / 编辑 / 删除。
| 操作 | 方法 | 地址 |
|---|---|---|
| 列表 | GET | /authorization-resources?type=api&page-token=&page-size=&page-direction= |
| 新增 | POST | /authorization-resources |
| 修改 | PATCH | /authorization-resources/{resource-id} |
| 删除 | DELETE | /authorization-resources/{resource-id} |
新增时 resourceId 由 getAppClientId() 生成,type 固定为 api。
React
import {
ResourceManager,
createAuthorizationResourceApi,
createDefaultResourceRequest,
} from 'com-angel-authorization/react';
const api = createAuthorizationResourceApi(
createDefaultResourceRequest({ baseUrl: '/api' }),
);
export function Page() {
return <ResourceManager api={api} />;
}
也可注入宿主已有请求(如 Angel_HGAMS 的 apiGetJson):
import { createAuthorizationResourceApi } from 'com-angel-authorization';
import { apiDeleteJson, apiGetJson, apiPatchJson, apiPostJson } from './request';
const api = createAuthorizationResourceApi(async ({ method, url, body, signal }) => {
if (method === 'GET') return apiGetJson(url, { signal });
if (method === 'POST') return apiPostJson(url, body, { signal });
if (method === 'PATCH') return apiPatchJson(url, body, { signal });
return apiDeleteJson(url, { signal });
});
Vue 3
import { createApp } from 'vue';
import {
ResourceManager,
createAuthorizationResourceApi,
createDefaultResourceRequest,
} from 'com-angel-authorization/vue';
const api = createAuthorizationResourceApi(
createDefaultResourceRequest({ baseUrl: '/api' }),
);
createApp(ResourceManager, { api }).mount('#app');
表单字段
| 字段 | 说明 |
|---|---|
| name | 权限名称(文本) |
| identification | 接口标识(文本) |
| status | 1 启用 / 0 禁用 |
| private | 是否私有资源 |
| description | 描述 |
列表表头:权限名称、接口标识、描述、状态、操作。
菜单管理(CRUD)
对接同一后端 /authorization-resources,按 type 区分菜单与权限点。
| 操作 | 方法 | 地址 |
|---|---|---|
| 列表 | GET | /authorization-resources?type=page,menu,button&depth=1&page-token=&page-size=&page-direction= |
| 展开下级 | GET | /authorization-resources/{resource-id}/sub-resources |
| 新增 | POST | /authorization-resources |
| 修改 | PATCH | /authorization-resources/{resource-id} |
| 删除 | DELETE | /authorization-resources/{resource-id} |
| 权限点下拉 | GET | /authorization-resources?type=api&keyword=(输入关键字后带 keyword 搜索) |
| 字段列表 | GET | /authorization-resources/{resource-id}/fields |
| 新增字段 | POST | /authorization-resources/{resource-id}/fields |
| 修改字段 | PATCH | /authorization-resources/{resource-id}/fields/{field-key} |
| 删除字段 | DELETE | /authorization-resources/{resource-id}/fields/{field-key} |
新增时 resourceId 由 getAppClientId() 生成;上级选择「无」时 parentId 传 null。
React
import {
MenuManager,
createMenuResourceApi,
createDefaultResourceRequest,
} from 'com-angel-authorization/react';
const api = createMenuResourceApi(
createDefaultResourceRequest({ baseUrl: '/api' }),
);
export function Page() {
return <MenuManager api={api} />;
}
表单字段
| 字段 | 说明 |
|---|---|
| parentId | 上级菜单(表单内只读展示;行内「新增」默认当前项,顶部「新增」为无) |
| depth | 菜单层级(页面不展示;无上级为 1,否则上级 depth + 1,提交时自动带上) |
| type | page 目录 / menu 菜单 / button 按钮 |
| name | 菜单名称 |
| sort | 显示排序(数值越小越靠前) |
| identification | 请求地址 |
| permissionPointIds | 权限标识(多选,来自 type=api 列表) |
| status | 1 显示 / 0 隐藏 |
列表默认 depth=1。返回项 leaf=1 表示无下级;否则可点击展开,请求 /authorization-resources/{resource-id}/sub-resources。
列表表头:菜单名称、请求地址、类型、可见、权限标识、操作(新增 / 编辑 / 数据列 / 删除)。
权限标识列优先取返回的 permissionPoints[].name,用 、 拼接展示。
点击「数据列」打开「页面数据列配置」弹窗(仅 type=menu 的菜单项显示该按钮),维护本页面可授权字段(fieldKey / name / description / viewTypes:LIST | DETAIL | EXPORT)。字段标识创建后不可修改;删除字段会同步清理角色侧该字段可见性配置。
角色管理(CRUD)
对接后端 /system/roles。
| 操作 | 方法 | 地址 |
|---|---|---|
| 列表 | GET | /system/roles?keyword=&page-token=&page-size=&page-direction= |
| 新增 | POST | /system/roles |
| 修改 | PATCH | /system/roles/{role-id} |
| 删除 | DELETE | /system/roles/{role-id} |
| 授权树 | GET | /system/roles/{role-id}/permissions |
| 保存授权 | POST | /system/roles/{role-id}/permissions |
| 数据范围 | GET | /system/roles/{role-id}/default-data-scope |
| 保存数据范围 | PUT | /system/roles/{role-id}/default-data-scope |
| 页面授权树 | GET | /system/roles/{role-id}/page-data-authorizations |
| 页面授权配置 | GET | /system/roles/{role-id}/page-data-authorizations/{resource-id} |
| 保存页面授权 | PUT | /system/roles/{role-id}/page-data-authorizations/{resource-id} |
| 删除页面例外 | DELETE | /system/roles/{role-id}/page-data-authorizations/{resource-id} |
授权树返回 resourceIds(已勾选资源 ID)与 resourceTree(含 name / children 的树)。保存时提交 { resourceIds }。
React
import {
RoleManager,
createSystemRoleApi,
createDefaultResourceRequest,
} from 'com-angel-authorization/react';
const api = createSystemRoleApi(
createDefaultResourceRequest({ baseUrl: '/api' }),
);
export function Page() {
return <RoleManager api={api} />;
}
表单字段
| 字段 | 说明 |
|---|---|
| name | 角色名称 |
| description | 角色描述 |
列表支持 keyword 搜索与 page-token 分页。表头:角色名称、描述、操作(编辑 / 菜单授权 / 数据授权 / 页面授权 / 删除)。
点击「菜单授权」打开树形勾选弹窗(父子联动:勾选父节点级联子节点;子节点全选/取消会回写父节点;部分勾选为半选态)。保存调用 POST /system/roles/{role-id}/permissions。
点击「数据授权」打开数据范围弹窗:scopeType 为 ALL / USER_GROUP / CUSTOM / SELF;选「自定义部门数据」时需至少勾选一个部门(部门列表来自 GET /system/groups)。保存调用 PUT /system/roles/{role-id}/default-data-scope,body 为 { scopeType, departmentIds }(非 CUSTOM 时 departmentIds 为空数组)。
点击「页面授权」打开页面数据授权弹窗:左侧为已授权业务页面树(GET .../page-data-authorizations);选中页面后加载例外配置(GET .../page-data-authorizations/{resource-id},scopeType=null 表示继承默认)与登记字段(GET /authorization-resources/{resource-id}/fields)。本页数据范围可选继承默认 / 本部门 / 全部数据 / 自定义部门;点击「继承默认」立即 DELETE 页面例外。保存调用 PUT .../page-data-authorizations/{resource-id},提交完整 fieldPermissions。
用户管理(CRUD)
对接后端 /system/users。
| 操作 | 方法 | 地址 |
|---|---|---|
| 列表 | GET | /system/users?keyword=&enabled=&page-token=&page-size=&page-direction= |
| 新增 | POST | /system/users |
| 修改 | PATCH | /system/users/{user-id} |
| 删除 | DELETE | /system/users/{user-id} |
| 重置密码 | POST | /system/users/{user-id}/reset-password(body: { password }) |
| 部门下拉 | GET | /system/groups?keyword= |
| 角色下拉 | GET | /system/roles?keyword=&page-size=500&page-token=&page-direction=current |
React
import {
UserManager,
createSystemUserApi,
createDefaultResourceRequest,
} from 'com-angel-authorization/react';
const api = createSystemUserApi(
createDefaultResourceRequest({ baseUrl: '/api' }),
);
export function Page() {
return <UserManager api={api} />;
}
表单字段
| 字段 | 说明 |
|---|---|
| username | 账号,必填,按普通字符串处理 |
| name | 用户名 |
| password | 初始密码(仅新增时填写;编辑请用「重置密码」) |
| groupIds | 归属部门,必填;进入模块时请求 /system/groups,列表按 name 展示,表单下拉多选 |
| roleIds | 用户角色,多选(/system/roles) |
| enabled | 是否启用(boolean,Switch,靠左) |
列表支持 keyword、enabled 过滤与 page-token 分页。
系统管理(含子菜单)
将「菜单管理」「权限点管理」「角色管理」「用户管理」作为「系统管理」的子菜单展示:
import {
SystemAdmin,
createMenuResourceApi,
createAuthorizationResourceApi,
createSystemRoleApi,
createSystemUserApi,
createDefaultResourceRequest,
SYSTEM_ADMIN_MENU,
} from 'com-angel-authorization/react';
const request = createDefaultResourceRequest({ baseUrl: '/api' });
const menuApi = createMenuResourceApi(request);
const resourceApi = createAuthorizationResourceApi(request);
const roleApi = createSystemRoleApi(request);
const userApi = createSystemUserApi(request);
// 侧栏:系统管理 → 菜单 / 权限点 / 角色 / 用户管理
<SystemAdmin
menuApi={menuApi}
resourceApi={resourceApi}
roleApi={roleApi}
userApi={userApi}
/>
// 也可把菜单结构接到自有路由
console.log(SYSTEM_ADMIN_MENU);
// { key: 'system', label: '系统管理', children: [
// { key: 'menu', label: '菜单管理' },
// { key: 'resource', label: '权限点管理' },
// { key: 'role', label: '角色管理' },
// { key: 'user', label: '用户管理' },
// ]}
典型接入流程
- 应用启动时创建 store / 安装 Provider 或 Plugin
- 登录成功后调用
hydrate写入后端返回的权限与角色 - 页面用
<Can>/v-permission/can()控制按钮与菜单 - 路由守卫中直接读同一个 store 做页面级鉴权
- 登出时调用
clear()
// 路由守卫示例(与框架无关)
if (!permissionStore.hasPermission('order:view')) {
return next('/403');
}
构建
npm install
npm run build
./scripts/publish.sh minor
npm install com-angel-authorization@latest
产物在 dist/,支持 ESM / CJS 与类型声明。
License
MIT
Related Packages
Permix is a lightweight, framework-agnostic, type-safe permissions management li...
A unified permission system for Vue 3 and Nuxt 3 / Nuxt 4 with directives, guard...
Vue 3 bindings for Better IAM: a plugin, composables for the session and authori...
Vue plugin for CASL which makes it easy to add permissions in any Vue applicatio...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 2.1.0 | >=3.0.0 | MIT | |
| 2.0.15 | >=3.0.0 | MIT | |
| 2.0.13 | >=3.0.0 | MIT | |
| 2.0.12 | >=3.0.0 | MIT | |
| 2.0.11 | >=3.0.0 | MIT | |
| 2.0.10 | >=3.0.0 | MIT | |
| 2.0.9 | >=3.0.0 | MIT | |
| 2.0.8 | >=3.0.0 | MIT | |
| 2.0.7 | >=3.0.0 | MIT | |
| 2.0.6 | >=3.0.0 | MIT | |
| 2.0.5 | >=3.0.0 | MIT | |
| 2.0.4 | >=3.0.0 | MIT | |
| 2.0.3 | >=3.0.0 | MIT | |
| 2.0.2 | >=3.0.0 | MIT | |
| 2.0.1 | >=3.0.0 | MIT | |
| 2.0.0 | >=3.0.0 | MIT | |
| 1.0.34 | >=3.0.0 | MIT | |
| 1.0.33 | >=3.0.0 | MIT | |
| 1.0.32 | >=3.0.0 | MIT | |
| 1.0.31 | >=3.0.0 | MIT | |
| 1.0.30 | >=3.0.0 | MIT | |
| 1.0.29 | >=3.0.0 | MIT | |
| 1.0.28 | >=3.0.0 | MIT | |
| 1.0.27 | >=3.0.0 | MIT | |
| 1.0.26 | >=3.0.0 | MIT | |
| 1.0.25 | >=3.0.0 | MIT | |
| 1.0.24 | >=3.0.0 | MIT | |
| 1.0.23 | >=3.0.0 | MIT | |
| 1.0.22 | >=3.0.0 | MIT | |
| 1.0.20 | >=3.0.0 | MIT |
Showing the latest 30 of 47. See every release on npm