# @dupecom/botcha-verify 中文文档

规范地址：https://npmcn.com/package/%40dupecom/botcha-verify/

版本：0\.2\.0
npm 元数据更新时间：2026-02-15T16:00:08.854Z
中文译文更新时间：2026-11-13T00:31:30.482Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40dupecom/botcha-verify
原文对照：https://npmcn.com/package/%40dupecom/botcha-verify/?lang=original
项目主页：https://botcha.ai/
源码仓库：https://github.com/dupe-com/botcha

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

- 包体积（解压后）：42.8 kB，18 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：1 个
- peer 依赖：express ^4\.0\.0 \|\| ^5\.0\.0，hono ^4\.0\.0 \|\| ^5\.0\.0
- 首次发布：2026-02-15T15:38:24.910Z
- 最新版本发布：2026-02-15T16:00:08.716Z
- 近 30 天下载量：8292（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：2（近 12 个月 2 个）

## 中文简介

BOTCHA JWT 信使的服务器端验证中间软件

## 安装

```sh
npm install @dupecom/botcha-verify
```

也可以使用：`pnpm add @dupecom/botcha-verify`、`yarn add @dupecom/botcha-verify`、`bun add @dupecom/botcha-verify`

## README

# @dupecom/botcha-验证

用于 BOTCHA JWT 令牌的服务器端验证中间软件.

## 安装

```bash
npm install @dupecom/botcha-verify
# or
yarn add @dupecom/botcha-verify
# or
bun add @dupecom/botcha-verify
```

## 特征

-   **JWKS核查(ES256)** ——不需要共享秘密,密钥自动旋转
-   HS256 共同秘密核查(遗产,仍得到支持)
-   自动检查过期
-   观众索赔的确认
-   发行人验证( I)`botcha.ai`JWKS 模式
-   客户端 IP 绑定支持
-   托肯撤销检查( 可选)
-   快速和 Hono 中间软件
-   带有完整类型定义的脚本类型支持
-   自定义错误处理器

## 使用量

### JWKS 核查(建议)

推荐的方法从JWKS端取出BOTCHA的公钥. 没有共享的机密管理——密钥旋转自动处理.

```typescript
import { verifyBotchaToken } from '@dupecom/botcha-verify';

const result = await verifyBotchaToken(token, {
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  audience: 'https://api.example.com',
});

if (result.valid) {
  console.log('Token valid! Challenge:', result.payload.sub);
  console.log('Solve time:', result.payload.solveTime, 'ms');
} else {
  console.error('Token invalid:', result.error);
}
```

### 遗产:共享秘密核查

仍然支持使用HS256令牌的现有整合.

```typescript
import { verifyBotchaToken } from '@dupecom/botcha-verify';

const result = await verifyBotchaToken(token, {
  secret: process.env.BOTCHA_SECRET!,
  audience: 'https://api.example.com',
  requireIp: true,
});
```

### 表达式中件

```typescript
import express from 'express';
import { botchaVerify } from '@dupecom/botcha-verify/express';

const app = express();

// RECOMMENDED: JWKS verification
app.use('/api', botchaVerify({
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  audience: 'https://api.example.com',
}));

// LEGACY: Shared secret
app.use('/api', botchaVerify({
  secret: process.env.BOTCHA_SECRET!,
  audience: 'https://api.example.com',
  requireIp: true,
}));

app.get('/api/protected', (req, res) => {
  console.log('Challenge ID:', req.botcha?.sub);
  console.log('Solve time:', req.botcha?.solveTime);
  res.json({ message: 'Success' });
});
```

### Hono 中间软件

```typescript
import { Hono } from 'hono';
import { botchaVerify } from '@dupecom/botcha-verify/hono';
import type { BotchaTokenPayload } from '@dupecom/botcha-verify';

const app = new Hono<{ Variables: { botcha: BotchaTokenPayload } }>();

// RECOMMENDED: JWKS verification
app.use('/api/*', botchaVerify({
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  audience: 'https://api.example.com',
}));

// LEGACY: Shared secret
app.use('/api/*', botchaVerify({
  secret: env.BOTCHA_SECRET,
  audience: 'https://api.example.com',
  requireIp: true,
}));

app.get('/api/protected', (c) => {
  const botcha = c.get('botcha');
  console.log('Challenge ID:', botcha.sub);
  console.log('Solve time:', botcha.solveTime);
  return c.json({ message: 'Success' });
});
```

## API 密码

### `verifyBotchaToken(token, options, clientIp?)`

检查一个BOTCHA JWT标志.

**参数:**

-   `token` (字符串):JWT验证符
-   `options` (BotchaVrify options):核查选项(至少其中一种) `secret` 或者说 `jwksUrl` (所需)
-   `clientIp` (弦,可选): 用于验证的客户端 IP

**回返情况:** `Promise<VerificationResult>`

```typescript
interface VerificationResult {
  valid: boolean;
  payload?: BotchaTokenPayload;
  error?: string;
}
```

### `BotchaVerifyOptions`

```typescript
interface BotchaVerifyOptions {
  // JWKS URL for ES256 verification (recommended)
  jwksUrl?: string;

  // Cache JWKS keys for this many seconds (default: 3600)
  jwksCacheTtl?: number;

  // JWT secret for HS256 verification (legacy)
  secret?: string;

  // At least one of `secret` or `jwksUrl` must be provided.
  // If both are provided, JWKS is tried first, falling back to secret.

  // Optional: Expected audience claim
  audience?: string;

  // Optional: Validate client IP claim
  requireIp?: boolean;

  // Optional: Custom error handler
  onError?: (error: string, context: VerificationContext) => void | Promise<void>;

  // Optional: Token revocation check
  checkRevocation?: (jti: string) => Promise<boolean>;
}
```

### `BotchaTokenPayload`

```typescript
interface BotchaTokenPayload {
  sub: string;        // Challenge ID
  iat: number;        // Issued at
  exp: number;        // Expires at
  jti: string;        // JWT ID
  type: 'botcha-verified';
  solveTime: number;  // Solve time in ms
  aud?: string;       // Optional audience
  client_ip?: string; // Optional client IP
}
```

## 托肯验证

核查人检查:

1.  **签署**:ES256通过JWKS(推荐)或HS256通过共享秘密(遗产)
2.  **过期**: 切入不能过期
3.  **类型**: 托肯必须是 `botcha-verified` (无) `botcha-refresh`(中文(简体) )
4.  **发行人** (JWKS模式):托肯 `iss` 必须是 `botcha.ai`
5.  **观众** (可选):托肯 `aud` 必须与预期受众匹配
6.  **客户端IP** (可选):托肯 `client_ip` 必须匹配请求 IP
7.  **撤销** (可选) : Token JTI 不可撤销

## 从共享机密向JWKS的迁移

替换 `secret` 与 `jwksUrl` 在您的配置中。 过渡时期 您可以同时提供 —— JWKS 被先尝试后退至秘密 :

```typescript
// Transition: both methods supported
app.use('/api', botchaVerify({
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  secret: process.env.BOTCHA_SECRET!, // fallback during migration
  audience: 'https://api.example.com',
}));

// After migration: JWKS only
app.use('/api', botchaVerify({
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  audience: 'https://api.example.com',
}));
```

## 自定义错误处理

```typescript
app.use('/api', botchaVerify({
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  onError: (error, context) => {
    console.error('Token verification failed:', error);
    console.error('Context:', context);
  },
}));
```

## Token 撤销

执行自定义撤销检查 :

```typescript
import { verifyBotchaToken } from '@dupecom/botcha-verify';

const result = await verifyBotchaToken(token, {
  jwksUrl: 'https://botcha.ai/.well-known/jwks',
  checkRevocation: async (jti) => {
    const isRevoked = await db.revokedTokens.exists(jti);
    return isRevoked;
  },
});
```

## 客户IP提取器

中间软件自动从 :

-   **云雾花**数字 : `CF-Connecting-IP` 标题
-   **代理**数字 : `X-Forwarded-For` 页眉( 第一个 IP)
-   **装入平衡器**数字 : `X-Real-IP` 标题
-   **直接**数字 : `req.ip` (出)或倒(呼诺)

## 安全说明

-   **犹太人**: 公共密钥被缓存并自动旋转 `jose` 图书馆
-   **未打开**: 如果检查出错, 撤销检查失败打开
-   **IP 验证**: 仅在 `requireIp: true` 设定
-   **观众**: 强烈建议部署多API
-   **发行人**: 自动验证为 `botcha.ai` 在 JWKS 模式下

## 许可证

麻省理工学院

## 链接

-   [文档](https://botcha.ai/)
-   [GitHub 图像](https://github.com/dupe-com/botcha)
-   [国家预防机制](https://www.npmjs.com/package/@dupecom/botcha-verify)

## 常见问题

### @dupecom/botcha-verify 是什么？

BOTCHA JWT 信使的服务器端验证中间软件

### 如何安装 @dupecom/botcha-verify？

在项目目录运行 npm install @dupecom/botcha-verify，或使用 pnpm add / yarn add / bun add。

### @dupecom/botcha-verify 支持 TypeScript 吗？

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

### @dupecom/botcha-verify 支持 ESM 还是 CommonJS？

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

### @dupecom/botcha-verify 需要什么版本的 Node\.js？

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

### @dupecom/botcha-verify 可以商用吗？

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

### @dupecom/botcha-verify 的下载量有多少？

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

### @dupecom/botcha-verify 还在维护吗？

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

