# @factorialco/auth 中文文档

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

版本：0\.3\.0
npm 元数据更新时间：2026-07-28T10:12:18.543Z
中文译文更新时间：2026-11-14T08:27:54.666Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：267 kB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.14\.0
- 运行依赖：2 个
- 首次发布：2026-07-14T09:50:33.112Z
- 最新版本发布：2026-07-28T10:12:18.166Z
- 近 30 天下载量：51425（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：3（近 12 个月 3 个）

## 中文简介

校验身份标识符并请求 OAuth 授权 .

## 安装

```sh
npm install @factorialco/auth
```

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

## README

# @ factorialco/ auth (帮助)

校验阶乘代号, 并请求 OAuth 从它的标志端点获得赠款 .

库-不可知:它只取决于 [`jose`](https://github.com/panva/jose) 和全球 `fetch`, (中文(简体) ), 所以它继续运行 **节点.js (>= 22.14)** 继续 **边缘/ 无服务器** 运行时间.

-   通过 **OIDC 发现** (作相克相克相克相克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克.
-   验证符(默认为ES256): **签名, `iss`, (中文(简体) ), `aud`, (中文(简体) ), `exp`, (中文(简体) ), `nbf`**。 。 。 .
-   自动调试 JWKS **键旋转** (不详) `kid`) (中文(简体) ).
-   回返 **严格、打字、不可改变** 权利主张对象.
-   请求平台,授权,并通过已发现的终点刷新OAuth标志.
-   船舶演员身份值对象: `ActorRef`, (中文(简体) ), `ActorType`, (中文(简体) ), `IdentityChain`, (中文(简体) ), `ActType`。 。 。 .
-   提供框架不可知性 `extractBearerToken` 帮手.

* * *

## 安装

```bash
pnpm add @factorialco/auth
# or: npm install / yarn add / bun add
```

## 快开始

```ts
import { FactorialAuth } from '@factorialco/auth'

const auth = new FactorialAuth({
  oidcDiscoveryUrl: 'https://id.factorialhr.com/.well-known/openid-configuration',
  audience: 'your-client-id',
})

// Decode and verify an access token
const accessTokenClaim = await auth.decodeAccessToken(token)
console.log(accessTokenClaim.sub, accessTokenClaim.cid)

// Decode and verify an id token
const idTokenClaim = await auth.decodeIdToken(token)
console.log(idTokenClaim.sub, idTokenClaim.email)
```

建筑费用低廉、同步 解码或代号客户呼叫。 发现和JWKS文件被懒散地取出 然后缓存( 见 [缓存密钥旋转( K)](https://npmcn.com/package/%40factorialco/auth/#readme-caching--key-rotation)) (中文(简体) ).

## OAuth 令牌客户端

配置相同的客户端证书 `FactorialAuth` 举个例子 全权证书 仅当一个符号客户端操作被称为:

```ts
const auth = new FactorialAuth({
  oidcDiscoveryUrl: process.env.FACTORIAL_OIDC_DISCOVERY_URL!,
  audience: 'factorial',
  clientId: process.env.FACTORIAL_OAUTH_CLIENT_ID,
  clientSecret: process.env.FACTORIAL_OAUTH_CLIENT_SECRET,
})

const platform = await auth.tokenClient.platformToken({
  audience: 'factorial-backend',
  cell: 'eu1',
})

const delegated = await auth.tokenClient.delegatedToken({
  subjectToken,
  audience: 'factorial-backend',
})

const refreshed = await auth.tokenClient.refreshToken(refreshToken)
```

信使客户端解析 OAuth 响应, 但不会解码、 校验、 坚持, 自动刷新或撤销退回的赠款。 申请保留所有权 这些生命周期和授权决定.

当符号端点以 OAuth 错误回答时, 抛出 `TokenRequestError` 曝光 HTTP `status` 和奥地利 `error` 代码为 `oauthError`,所以呼叫者可以在不解析消息的情况下进行分支. 从 符号终点从未被遵循.

## 演员身份原始人

`ActorRef` 财务报告和审定财务报表 `IdentityChain` 为小值对象 携带经认证的演员身份跨越应用程序界限。 他们是 认证原始, 不授权背景和事件传输 对象.

### 演员参考

`ActorRef` 这是对一个具体行为者的不可改变的提法.

它回答:"这是哪个演员?"

```ts
import { ActorRef } from '@factorialco/auth'

ActorRef.employee('123')
ActorRef.company('42')
ActorRef.system('domain-events-audit-log-creator')
```

一名演员将序列化为类似URI的字符串:

```text
f:act:employee:123
```

使用一个 `ActorRef` 当代码需要紧凑,稳定的演员标识符时,不需要 装入模型、携带许可或编码租户范围。 号码是 总是一个字符串,必须不透明: 永远不要放邮件,姓名, API 密钥, 符号, IP,或其中的其他敏感值.

### 身份号码

`IdentityChain` 是一个递归链 演员参考.

它回答:"谁是有效的认证演员,谁在演 "通过谁?"

链根是当前行动的有效行为者. 如果动作 发生在一个变相/动作流, `act` 指向演员链 发起,并 `actType` 描述这两个节点之间的关系.

```ts
import { ActorRef, ActType, IdentityChain } from '@factorialco/auth'

const employee = ActorRef.employee('123')
const admin = ActorRef.employee('999')

const identityChain = IdentityChain.create({
  actor: employee,
  act: IdentityChain.create({ actor: admin }),
  actType: ActType.AdminBecome,
})

identityChain.actor // employee
identityChain.act?.actor // admin
```

串行形状为串键并递归(线形使用: 蛇脚( c) `act_type`:

```ts
identityChain.toObject()

// {
//   actor: "f:act:employee:123",
//   act: { actor: "f:act:employee:999" },
//   act_type: "admin_become",
// }
```

使用 `IdentityChain.parse` 仅用于信任的服务器侧元数据. 取消序列化默认在3个节点封顶,以保持解析保守; 2; 通过 `maxDepth` 改为:

```ts
IdentityChain.parse(serializedObject)
IdentityChain.parse(serializedObject, { maxDepth: 5 })
```

### 关系如何

`ActorRef` 是叶值。 它能识别一个演员 而不是别的.

`IdentityChain` 编剧将角色重置为认证的关系图. 保持了角色参考的稳定性和简洁性,同时保留了成/行 明确上下文。 不将冒用链条编码为演员参考字符串; 将演员推为主题并使用 `IdentityChain.act` 加号 `IdentityChain.actType` 为了关系.

例如,成为雇员的管理人员有:

```text
employee actor ref -> act(admin actor ref), actType: admin_become
```

这样就可以让应用程序代码为自己的合同选择正确的投影.

绝不接受客户端提供的演员参考或身份链作为权威 写作。 从已认证的服务器侧上下文、 证书来构建这些对象 , 或已知的系统呼叫者。 演员代表是演员,不是房客 审计和领域活动流动必须分别包含公司或租户的范围.

## 处理错误

每一次校验/解码失败都投出一个子类: `AuthError`执行 `AuthError` 用来处理所有的, 或者一个特定的子类 更细的控制。 这个 `tryDecode*` 方法吞进 `AuthError` 返回时 `null`; 任何其他( 意外) 错误传播 .

```
Error
├─ AuthError                       // base for everything this library throws
│  ├─ ConfigurationError           // invalid FactorialAuthConfig (thrown by the constructor)
│  ├─ OidcDiscoveryFetchError      // discovery endpoint unreachable / non-2xx / timeout
│  ├─ OidcDiscoveryParseError      // discovery document invalid JSON or missing issuer/jwks_uri
│  ├─ TokenRequestError            // OAuth token endpoint request failed
│  ├─ TokenResponseParseError      // OAuth token response malformed or unusable
│  ├─ JwksFetchError               // JWKS endpoint unreachable / non-2xx / timeout
│  ├─ JwksParseError               // JWKS invalid JSON or malformed key set
│  └─ TokenError                   // base for token-level failures
│     ├─ InvalidToken              // bad signature, malformed token, unknown kid, or bad claim shape
│     ├─ ExpiredToken              // exp check failed
│     ├─ InvalidIssuer             // iss did not match the discovery document
│     ├─ InvalidAudience           // aud did not match config.audience
│     └─ ImmatureToken             // nbf check failed (token used before it is valid)
├─ ActorRefError                   // malformed ActorRef string/id (NOT an AuthError)
└─ IdentityChainError              // malformed identity chain (NOT an AuthError)
```

> 说明: `ActorRefError` 财务报告和审定财务报表 `IdentityChainError` 扩展 `Error` 直接, **没有** `AuthError`,并且不受 `tryDecode*`。 。 。 .

```ts
import { FactorialAuth, ExpiredToken, TokenError, OidcDiscoveryFetchError } from '@factorialco/auth'

try {
  const claims = await auth.decodeAccessToken(token)
} catch (error) {
  if (error instanceof ExpiredToken) {
    // prompt a refresh
  } else if (error instanceof TokenError) {
    // any other invalid-token case -> 401
  } else if (error instanceof OidcDiscoveryFetchError) {
    // upstream/infra problem -> 503
  } else {
    throw error
  }
}
```

## 缓存密钥旋转( K)

-   OIDC的发现文件和JWKS在内存中被缓存为双TTL: **新鲜10分钟**,然后服务 **暂停1小时以下** 如果反切 失败(所以瞬间发现/JWKS出局不会破坏验证).
-   同时进行的首次核查 **单人** 获取和获取 **单人** JWKS接取(飞行中的请求被去复制).
-   当一个符号带有一个 `kid` 在缓存的 JWKS(键旋转)中 JWKS 已调试 **一次** 和仰视重试。 如果 `kid` 仍然是 未知,该符号以 `InvalidToken`。 。 。 .

因为缓存住在实例上,创建 **一个** `FactorialAuth` 并重新使用它 您的流程/工作寿命, 而不是构建一个请求.

## 一体化模式

### 服务器请求处理器( Express- style)

```ts
import { FactorialAuth, extractBearerToken } from '@factorialco/auth'

const auth = new FactorialAuth({
  oidcDiscoveryUrl: process.env.FACTORIAL_OIDC_DISCOVERY_URL!,
  audience: process.env.FACTORIAL_AUDIENCE!,
})

app.use(async (req, res, next) => {
  const token = extractBearerToken(req.headers.authorization ?? null)

  if (token === null) {
    return res.status(401).json({ error: 'missing bearer token' })
  }

  const claims = await auth.tryDecodeAccessToken(token)

  if (claims === null) {
    return res.status(401).json({ error: 'invalid token' })
  }

  req.claims = claims
  next()
})
```

### 边缘/ 网络 `Request`

```ts
const token = extractBearerToken(request.headers.get('authorization'))
const claims = token ? await auth.tryDecodeAccessToken(token) : null
```

### A. 从访问控制索赔中确认的身份

Access-token 索赔使用 同一个员工,平台主,成为, 和授权规则与鲁比 `factorial-auth` 软件包 :

```ts
const claims = await auth.decodeAccessToken(token)
const actor = claims.actorRef
const chain = claims.identityChain()
```

`identityChain()` 掷出 `IdentityChainError` 当 `act` 链条更深 大于允许的最大值或携带未知的 `bt` 值——甚至一个符号 解码成功.

## 兼容性

-   **运行时间 :** 节点.js QQ 22.14, 以及任何带有全局的边缘/服务器运行时间 `fetch` 和网络加密(Cloudflare Workers, Vercel Edge, Deno, Bun).
-   **模块 :** 双重无害环境管理(`import`)和CJS(`require`(b) 有捆绑的切入点 `.d.ts`。 。 。 .

## 捐款

见 [捐款额](https://npmcn.com/package/%40factorialco/auth/CONTRIBUTING.md) 用于本地设置和发展命令.

## 常见问题

### @factorialco/auth 是什么？

校验身份标识符并请求 OAuth 授权 \.

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

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

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

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

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

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @factorialco/auth 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=22\.14\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

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

@factorialco/auth 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

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

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

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

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

