# @bsuite/auth 中文文档

规范地址：https://npmcn.com/package/%40bsuite/auth/

版本：1\.0\.1
npm 元数据更新时间：2026-09-18T08:16:18.155Z
中文译文更新时间：2026-11-08T20:38:25.817Z
软件包许可：UNLICENSED

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40bsuite/auth
原文对照：https://npmcn.com/package/%40bsuite/auth/?lang=original
项目主页：https://github.com/GaryOcean428/bsuite#readme
源码仓库：https://github.com/GaryOcean428/bsuite

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：117 kB，14 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-04-20T06:14:16.995Z
- 最新版本发布：2026-09-18T08:16:17.932Z
- 近 30 天下载量：2318（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：14（近 12 个月 14 个）

## 中文简介

BSuite OAuth 2.1 PKCE客户端——共享于CRM7,R80.4,布拉登,康杜特,和通通. 使用 JWKS 通过 jose 进行符号验证 .

## 安装

```sh
npm install @bsuite/auth
```

也可以使用：`pnpm add @bsuite/auth`、`yarn add @bsuite/auth`、`bun add @bsuite/auth`

## README

# @ bsuite/ auth (英语)

OAuth 2.1 PKCE客户端在BSuite应用程序(CRM7, Conduit, R80.4, Braden, Turput)之间共享. BSU是 OAuth 服务器;这个软件包是用于消耗它的其他应用程序的客户端.

## 同步登录和召回恢复

选入 [届会所有权协调员](https://npmcn.com/package/%40bsuite/auth/docs/session-ownership.md) 序列化 消费者SDK在同源标签上写作和登录。 消费者适配器接线, 交易快照约束和部署的核查仍然是必要的.

登录启动器应当使用 `attemptSilentAuthDetailed()`。继续使用 `authenticated`; 暂停 `redirecting` 或者说 `superseded`; 提供交互式恢复 `failed`。旧布尔帮助器仍然兼容,但无法区分预定导航和失败。 指派 `window.location` 不停止后续的 JavaScript .

路由调用 `hasPendingBusinessSuiteTransaction(state)`,这需要这个来源的完整,新的交易状态. 不从状态形状或存在不相关的后遗症键发送 。 遗产交易还需要其核查人、非记录和时间戳。 交易不完全需要新的签注 .

`BusinessSuiteOAuthExchangeUncertainError.recovery` 实值 `fresh-sign-in`:服务器可能在网络或响应-body故障前消耗了单用代码. 永远不要自动重放它。 回调错误处理器必须保存不相关的交易和较新的会话. 在开始交换之前抓取消费者的会话/日志生成器,并在核实后以及在进行信使或导航之前再次检查。 已经在飞行中的交换可以在签出后返回;其结果不得恢复上一个会话. 成功交换后,通过消费者的桥梁 `supabase.auth.setSession()` 在保护数据读取之前。 主机-本地会话存储仍然与跨应用 OAuth SSO 分离.

套件是故意小的——它默认生产出BSuite Supabase主机(`https://tuybltdrdefjblnplpqo.supabase.co`),支持针对持续开发的Supabase分支的 OAuth-server 明确覆盖,解决从 URI重定向 `VITE_APP_URL` (或 `NEXT_PUBLIC_APP_URL`)在有可用的情况下,并回到 `${window.location.origin}/auth/callback`它只取决于 `jose` jWKS验证.

## OAuth 服务器环境

生产消费者不需要额外的配置;OAuth服务器默认为生产出BSuite Supabase项目. 使用持续Supabase分支/项目的长期开发部署,必须设定该分支URL的其中一个变量:

-   `VITE_BSU_OAUTH_SUPABASE_URL` 用于构建 Vite 浏览器
-   `NEXT_PUBLIC_BSU_OAUTH_SUPABASE_URL` next.js 浏览器构建
-   `BSU_OAUTH_SUPABASE_URL` 用于服务器/构建时环境

接受的别名是 `VITE_BUSINESS_SUITE_SUPABASE_URL`, (中文(简体) ), `NEXT_PUBLIC_BUSINESS_SUITE_SUPABASE_URL`,以及 `BUSINESS_SUITE_SUPABASE_URL`。数值必须是表格中的 HTTPS Supabase 项目 URL `https://<project-ref>.supabase.co`;在将用户重定向到破损的 OAuth 流之前,无效的覆盖 .

## 安装

```bash
pnpm add @bsuite/auth
```

## 使用量

每个消费者应用都创建了薄薄的包装器,将共享的客户端再出口到其OAuth客户端ID上. 从CRM7中取出的例子(犬科参考文献——相同模式 `R80.4`, (中文(简体) ), `braden`, (中文(简体) ), `conduit`, (中文(简体) ), `throughput`:

```ts
// src/lib/business-suite-oauth.ts
import { createOAuthClient } from '@bsuite/auth';
export type { BusinessSuiteTokens, VerifiedUser } from '@bsuite/auth';

export const {
  signInWithBusinessSuite,
  exchangeCodeForTokens,
  refreshBusinessSuiteToken,
  verifyAccessToken,
  getUserInfo,
  clearBSTokens,
  startBSTokenRefresh,
  attemptSilentAuthDetailed,
} = createOAuthClient('30f76744-3e0b-40bf-abb8-8c587389802e'); // your app's OAuth client ID
```

然后把它接入授权的生命周期:

```ts
// On a login button click — schedules navigation to the OAuth server
void signInWithBusinessSuite();

// In your /auth/callback route, with `code` and `state` parsed from the URL
const { tokens, user } = await exchangeCodeForTokens(code, state);
localStorage.setItem('bs_access_token', tokens.access_token);
localStorage.setItem('bs_refresh_token', tokens.refresh_token);
localStorage.setItem('bs_user', JSON.stringify(user));
if (tokens.id_token) localStorage.setItem('bs_id_token', tokens.id_token);

// On app mount (e.g. AuthContext / AuthProvider) — try OIDC silent re-auth before showing the login UI
const result = await attemptSilentAuthDetailed();
// Stop on redirecting/superseded; navigate only on authenticated.

// Start the auto-refresh loop and capture the cleanup function
const stopRefresh: () => void = startBSTokenRefresh();
// later, e.g. on AuthContext unmount or sign-out:
stopRefresh();

// Sign-out — clear all 4 BS OAuth localStorage keys
clearBSTokens();
```

## API 密码

```ts
import type { OAuthClient, BusinessSuiteTokens, VerifiedUser } from '@bsuite/auth';

declare function createOAuthClient(clientId: string): OAuthClient;

interface OAuthClient {
  signInWithBusinessSuite(): Promise<void>;
  exchangeCodeForTokens(
    code: string,
    state: string,
  ): Promise<{ tokens: BusinessSuiteTokens; user: VerifiedUser }>;
  refreshBusinessSuiteToken(
    refreshToken: string,
  ): Promise<{ tokens: BusinessSuiteTokens; user: VerifiedUser }>;
  verifyAccessToken(token: string): Promise<VerifiedUser>;
  getUserInfo(accessToken: string): Promise<Record<string, unknown>>;
  clearBSTokens(): void;
  startBSTokenRefresh(): () => void; // returns a cleanup function
  attemptSilentAuth(): Promise<boolean>;
}

interface BusinessSuiteTokens {
  access_token: string;
  refresh_token: string;
  token_type: string;
  expires_in: number;
  id_token?: string;
}

interface VerifiedUser {
  sub: string;
  email?: string;
  name?: string;
  picture?: string;
  client_id?: string;
  role?: string;
}
```

## 行为说明

-   **`signInWithBusinessSuite`** 生成 PKCE `code_verifier`, (中文(简体) ), `code_challenge` (S/256), (中文(简体) ), `state`,和OIDC `nonce`,将其储存在 `localStorage` 带10分钟TTL哨,然后设定 `window.location.href` 向《争端解决协议》提交的报告 `/auth/v1/oauth/authorize` URL (中文(简体) ). 返回的"承诺"从不解决——页面通航.
-   **`exchangeCodeForTokens`** 验证 `state` (CSRF),读取存储的PCE验证器,帖子到 `/auth/v1/oauth/token`,然后JWKS-验证访问符和OIDC `id_token` 非ce(每个OIDC Core § 3.1.2.2的重播保护). 扔出状态不匹配,缺少验证器,非-2xx响应,或非ce不匹配.
-   **`refreshBusinessSuiteToken`** 员额 `/auth/v1/oauth/token` 与 `grant_type=refresh_token` 并在返回前通过JWKS验证新的访问符.
-   **`verifyAccessToken`** 使用缓存 JWKS (`jose`是因为 `createRemoteJWKSet`与 `issuer: "<supabase>/auth/v1"` 财务报告和审定财务报表 `audience: "authenticated"`. 仅RS256/ES256.
-   **`getUserInfo`** 开始 `/auth/v1/oauth/userinfo` 与提供的无记名标志 并返回解析的JSON尸体.
-   **`startBSTokenRefresh`** 立即进行检查,然后每60秒进行一次民意测验,并在到期前5分钟刷新标志. 返回一个停止间隔的清理函数. **总是抓取清理** 以避免在挂载/卸载组件(例如AuthProvider)中泄漏定时器.
-   **`attemptSilentAuth`** 返回时 `true` 如果在 localStorage 中已经存在有效的访问令牌,或者有一个可以成功交换的刷新令牌. 回返 `false` 否则。 永不抛出——错误被吞入,所以登录UI仍然可以渲染出.
-   **`clearBSTokens`** 删除 `bs_access_token`, (中文(简体) ), `bs_refresh_token`, (中文(简体) ), `bs_user`, (中文(简体) ), `bs_id_token` 从本地Storage。 总是打电话签到.

## 存储密钥

| 存储 | 密钥 | 目的 | 终身 |
| --- | --- | --- | --- |
| `localStorage` | `bs_access_token` | JWT 访问符 (JWKS- 验证) | 直到刷新/ 签出 |
| `localStorage` | `bs_refresh_token` | 刷新符号 | 直到刷新/ 签出 |
| `localStorage` | `bs_user` | JSON 序列化 `VerifiedUser` | 直到刷新/ 签出 |
| `localStorage` | `bs_id_token` | OIDC id token (可选) | 直到刷新/ 签出 |
| `localStorage` | `bs_oauth_code_verifier` | PKCE 代码验证器 | 仅登录入流, TTL 守护 |
| `localStorage` | `bs_oauth_state` | CSRF 状态 | 仅登录入流, TTL 守护 |
| `localStorage` | `bs_oauth_nonce` | OIDC 重放保护非ce | 仅登录入流, TTL 守护 |
| `localStorage` | `bs_oauth_started_at` | PKCE TTL 监视器 | 仅输入流程 |
| `localStorage` | `bs_oauth_flows` | 国有证券交易 | 十分钟/完成/退出 |
| `localStorage` | `bs_oauth_inflight_codes` | 具有所有者身份的每个编码索偿 | 十分钟/完成/退出 |

## 设计说明

-   **每个域 `localStorage`** ——道具从不离开应用的自产地. 通过OIDC实现跨应用SSO `prompt=none` 静静地重现( s)`attemptSilentAuth`),非跨域饼干. 堕落者 `business_suite_auth` cookie SSO计划被删除了 2025-02-27; 不要重新引入.
-   **JWKS 验证** —— 说 `verifyAccessToken` 获取 Supabase `/.well-known/jwks.json` 一次并缓存它通过 `jose`是因为 `createRemoteJWKSet`. 仅RS256/ES256.
-   **第256号强制性规定** ——没有隐性流动,没有 `plain` 挑战.
-   **OIDC 非ce 验证** 如果 `id_token` 返回时,其 `nonce` 在匹配的按国家键交易(或符合资格的遗留交易)中,对索赔进行非ce核查。 缺失或错配的非ce会投出"id token noce错配——可能的回放攻击"(OIDC Core §3.1.2.2).
-   **托肯过期事件** 如果自动更新回路失败, 或删除了兄弟姐妹标签 `bs_access_token`,包发送 a `bs-oauth-expired` `CustomEvent` 打开 `window` 因此,应用程序可以在令牌被清除之前做出反应(例如显示一面横幅). 原因: `network_error`, (中文(简体) ), `refresh_rejected`, (中文(简体) ), `cross_tab_logout`。 。 。 .

## Per- app OAuth 客户端标识

| 应用 | 客户身份 |
| --- | --- |
| 风险管理7 | `30f76744-3e0b-40bf-abb8-8c587389802e` |
| 第80.3号公路 | `5d804d20-cd1b-4724-9107-86d2a9e51e09` |
| 布莱登 | `dcb7af18-254a-4946-b94d-5c606b01fc3f` |
| 吞吐量 | `35f0db49-ef62-4115-baba-7b961f034cc3` |
| 管道 | `da925c19-8f32-40a0-b74d-4eb9540c422f` |

## 相关文件

-   父复方舟认证架构 : [`AUTH_CANONICAL.md`](https://npmcn.com/package/AUTH_CANONICAL.md)
-   每个应用的整合:每个消费者的 `src/lib/business-suite-oauth.ts`

## 许可证

UNLICENSED(只使用内部套件).

## 常见问题

### @bsuite/auth 是什么？

BSuite OAuth 2\.1 PKCE客户端——共享于CRM7,R80\.4,布拉登,康杜特,和通通\. 使用 JWKS 通过 jose 进行符号验证 \.

### 如何安装 @bsuite/auth？

在项目目录运行 npm install @bsuite/auth，或使用 pnpm add / yarn add / bun add。

### @bsuite/auth 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @bsuite/auth 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @bsuite/auth 可以商用吗？

@bsuite/auth 使用 UNLICENSED 许可。作者声明为 UNLICENSED，即不授予公开使用许可（与公共领域的 Unlicense 不同）。使用前需获得作者授权。以上为概括，不构成法律意见，请以许可原文为准。

### @bsuite/auth 的下载量有多少？

根据 npm 官方下载统计，@bsuite/auth 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,318 次，日均约 77 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @bsuite/auth 还在维护吗？

最新版本 1\.0\.1 发布于 2026/09/18（1 个月前）；至今共发布 14 个版本，其中过去 12 个月发布了 14 个；首次发布于 2026/04/20。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

