npm package: @lark-apaas/auth-sdk
Description: 基于 CASL 的前端鉴权 SDK
Latest version: 0.1.4

# @lark-apaas/auth-sdk

基于 CASL 的前端鉴权 SDK，封装了权限数据获取、Ability 初始化与 React 集成，帮助你在应用中便捷地做「功能级/按钮级/菜单级/页面级」的权限控制。

## 安装

```bash
npm i @lark-apaas/auth-sdk
# 或者
yarn add @lark-apaas/auth-sdk
```

## 快速开始

### 模版接入

```tsx
import React from 'react';
import { AuthProvider, CanRole, useAuth } from '@lark-apaas/auth-sdk';

export default function App() {
  return (
    <AuthProvider
      config={{
        permissionApi: {
          timeout: 5000,
        },
        enable: true,
        onError: (e) => console.error(e),
      }}
    >
      <Home />
    </AuthProvider>
  );
}
```


### 开发组件 - 使用 CanRole 组件

```tsx
import { CanRole } from '@lark-apaas/auth-sdk';

function Home() {
  return (
    <div>
      <CanRole roles={['role_admin']}>
        <div>管理员按钮</div>
      </CanRole>
      <CanRole roles={['role_admin', 'role_editor']}>
        <div>编辑按钮</div>
      </CanRole>
    </div>
  );
}
```

### 开发组件 - 使用 AbilityContext 处理复杂场景

```tsx
import { useContext } from 'react';
import { AbilityContext, ROLE_SUBJECT } from '@lark-apaas/auth-sdk';

function Home() {
  const ability = useContext(AbilityContext);
  return (
    <div>
      {ability.can('role_admin', ROLE_SUBJECT) || ability.can('role_editor', ROLE_SUBJECT) ? (
        <div>可见的仪表盘</div>
      ) : null}
    </div>
  );
}
```

### 开发组件 - 见 Client Toolkit

---

## 核心 API - 面向 Agent

### CanRole 组件 (推荐)

- **作用**: 条件渲染，只有当角色 id 包含在 `roles` 中时才渲染子内容。

```tsx
<CanRole roles={['role_admin', 'role_editor']}>
  <button>删除任务</button>
</CanRole>
```

### AbilityContext 提供原子化的权限判断能力

- **作用**: 从 React 上下文获取 CASL `Ability` 实例，使用 `ability.can(action, subject)` 做权限判断。

```tsx
import { useContext } from 'react';
import { AbilityContext } from '@lark-apaas/auth-sdk';

const ability = useContext(AbilityContext);
const canCreate = ability.can('role_editor', '@role');
```

## 核心 API - 面向接入方

### AuthProvider

- **作用**: 提供 `Ability` 与权限状态上下文，自动/手动拉取权限。
- **Props**:
  - `config?: AuthSdkConfig`
    - `enable?: boolean` 是否启用权限 SDK，默认 false
    - `permissionApi?: PermissionApiConfig` 拉取权限接口配置
      - `timeout?: number`，默认 5000ms
      - `headers?: Record<string,string>` 自定义请求头
    - `onError?: (error: Error) => void`
    - `onSuccess?: (data: PermissionApiResponse) => void`
  - `children: React.ReactNode`

示例：

```tsx
<AuthProvider config={{
  enable: true,
}}>
  <App />
  {/* Can/Hook 在其子树中生效 */}
</AuthProvider>
```

## 核心 API - 面向 SDK 开发者

### PermissionClient

- **作用**: 独立的权限数据获取客户端，供非 React 场景（或自定义状态管理）使用。
- **方法**:
  - `constructor(config?: PermissionApiConfig)`
  - `fetchPermissions(userId?: string): Promise<PermissionApiResponse>`
  - `updateConfig(partial: Partial<PermissionApiConfig>): void`
  - `getConfig(): PermissionApiConfig`

```ts
import { PermissionClient } from '@lark-apaas/auth-sdk';

const client = new PermissionClient({ baseUrl: '/api', endpoint: '/users/:userId/permissions' });
const data = await client.fetchPermissions('user-123');
```

### 能力工厂（与 CASL 交互）

- `createAbility({ permissions?: Permission[], roles?: string[] }): Ability`
- `updateAbility(ability: Ability, { permissions?: Permission[], roles?: string[] }): void`
- `convertPermissionsToRules(permissions: Permission[], roles: string[]): CaslRule[]`

适用于需要在 React 之外构建/更新 `Ability` 的场景，或做 SSR/单元测试。

```ts
import { createAbility, updateAbility } from '@lark-apaas/auth-sdk';

const ability = createAbility({ permissions: [], roles: ['admin_role'] });
// 后续有新权限
updateAbility(ability, { permissions: [{ id: 'p1', name: 'Task Read', sub: 'Task', actions: ['read'] }], roles: [] });
```

---

## 类型与再导出

- 从本包导出的类型：`PermissionApiResponse`、`PermissionApiConfig`、`AuthSdkConfig`、`CaslRule`。
- 最终用户代码中仅需要使用到的 API 有：
  - `CanRole` 组件: 条件渲染，只有当角色 id 包含在 `roles` 中时才渲染子内容。
  - `AbilityContext`: 从 React 上下文获取 CASL `Ability` 实例，用于权限判断。
  - `ROLE_SUBJECT`: 特殊 subject `@role` 常量，用于角色判断。

## 集成建议与最佳实践

- **直接使用组件**：`CanRole` 组件是直接使用的主要入口，可以使用 `AbilityContext` 获取 `Ability` 实例，在特殊场景下手动判断权限。
- **与路由结合**：页面级的访问控制需要结合路由库（如 `react-router-dom`）和 `AbilityContext` 来自行实现。

---

## 许可

MIT