# 2fa-node 中文文档

规范地址：https://npmcn.com/package/2fa-node/

版本：1\.0\.0
npm 元数据更新时间：2026-09-30T14:55:26.649Z
中文译文更新时间：2026-11-08T03:06:54.924Z
软件包许可：MPL-2\.0

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

原始 npm 页面：https://www.npmjs.com/package/2fa-node
原文对照：https://npmcn.com/package/2fa-node/?lang=original
项目主页：https://github.com/finotilucas/2fa-node#readme
源码仓库：https://github.com/finotilucas/2fa-node

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

- 包体积（解压后）：45.1 kB，15 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=20\.19\.0
- 运行依赖：2 个
- 首次发布：2025-01-10T19:04:16.416Z
- 最新版本发布：2026-09-30T14:55:26.496Z
- 近 30 天下载量：1926（2026-10-04 至 2026-11-02，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 1 个）

## 中文简介

网易 2-Factor 集成为节点.js

## 安装

```sh
npm install 2fa-node
```

也可以使用：`pnpm add 2fa-node`、`yarn add 2fa-node`、`bun add 2fa-node`

## README

# 2FA NODE (英语:

该库生成并验证基于时间的一次性密码(TOTP,RFC 6238)和基于HMAC的一次性密码(HOTP,RFC 4226),用于双因子认证(2FA). 也创造了秘密 `otpauth://` URI和认证器应用的QR代码如Google认证器或Authy扫描.

## 特征

-   **生成 2FA 秘密**:一个随机基数32,其 `otpauth://` URI和那个URI的QR代码.
-   **生成和校验 TOTP 令牌**:6位码每30秒更改一次,可选择只接受每个令牌一次.
-   **生成并验证 HOTP 令牌**6位码绑在柜台上.

## 安装

```bash
npm install 2fa-node
```

需要节点20.19或以后.

## 使用量

### 生成 TOTP 秘密

```typescript
import { generateSecret } from "2fa-node";

const { secret, uri, qr } = await generateSecret({
  name: "MyApp", // issuer shown in the authenticator app
  account: "user@example.com", // account shown in the authenticator app
});

console.log(secret); // store it for the user
console.log(uri); // otpauth://totp/MyApp:user%40example.com?secret=...&issuer=MyApp
console.log(qr); // PNG data URL to show to the user
```

### 生成 HOTP 秘密

```typescript
import { generateSecret } from "2fa-node";

const { secret, uri, qr } = await generateSecret(
  { name: "MyApp", account: "user@example.com", counter: 0 },
  "HOTP",
);
```

### 校验 TOTP 令牌

```typescript
import { verifyToken } from "2fa-node";

const secret = "JBSWY3DPEHPK3PXP"; // the user's stored secret
const token = "123456"; // the token typed by the user

const isValid = verifyToken(secret, token);

console.log(isValid); // true if valid, false otherwise
```

### 只接受一次每个 TOTP 令牌

```typescript
import { verifyTokenOnce } from "2fa-node";

const secret = "JBSWY3DPEHPK3PXP"; // the user's stored secret
const token = "123456"; // the token typed by the user
const lastTimeStep = null; // the user's stored time step, null before the first login

const match = verifyTokenOnce(secret, token, lastTimeStep);

if (match) {
  // Save match.timeStep as the user's lastTimeStep, so this token cannot be used again.
}
```

### 生成 TOTP 令牌

```typescript
import { generateToken } from "2fa-node";

const secret = "JBSWY3DPEHPK3PXP";
const result = generateToken(secret);

console.log(result?.token); // the current token, or undefined if the secret is invalid
```

### 验证 HOTP 令牌

```typescript
import { verifyHOTPToken } from "2fa-node";

const secret = "JBSWY3DPEHPK3PXP"; // the user's stored secret
const token = "123456"; // the token typed by the user
const counter = 1; // the user's stored counter

const isValid = verifyHOTPToken(secret, token, counter);

if (isValid) {
  // Save counter + 1 so this token cannot be used again.
}
```

### 生成 HOTP 令牌

```typescript
import { generateHOTPToken } from "2fa-node";

const secret = "JBSWY3DPEHPK3PXP";
const counter = 1;

const result = generateHOTPToken(secret, counter);

console.log(result?.token); // the token, or undefined if the secret is invalid
```

## API 文档

托肯斯有6位数字,并使用HMAC-SHA1;TOTP令牌每30秒改变一次. 秘密是至少80个比特(16个字符)的大小写不敏感的基础32字符串.

### `generateSecret(options: SecretOptions, type: OtpType = "TOTP"): Promise<{ secret: string; uri: string; qr: string }>`

生成二因子认证的随机密钥 .

-   **参数**数字 :
    -   `options.name`: 认证器应用中显示的发行者,通常是您的产品名.
    -   `options.account`:在认证程序app中显示的账户,通常是用户的电子邮件.
    -   `options.counter` (可选):写给URI的初始HOTP计数器. 默认为 `0`;为TOTP忽略.
    -   `options.numberOfSecretBytes` (可选的):以字节表示的秘密大小. 默认为 `20`; 必须是至少是一个整数 `16`,因为RFC 4226需要128位密钥.
    -   `type`数字 : `"TOTP"` (违约)或 `"HOTP"`。 。 。 .
-   **回返**:承诺决心:
    -   `secret`: base32 为用户存储的密件.
    -   `uri`页:1 `otpauth://` URI (英语).
    -   `qr`:一个URI的QR代码的PNG数据URL.
-   **掷出**数字 : `TypeError` 用于未知的 `type`· ; `RangeError` 无效 `numberOfSecretBytes` 或 HOTP 语言 `counter`。 。 。 .

### `generateToken(secret: string): { token: string } | null`

生成当前 TOTP 令牌 .

-   **回返**数字 : `{ token }`,或 `null` 如果这个秘密无效.

### `verifyToken(secret: string, token?: string, window: number | [number, number] = 1): boolean`

验证一个 TOTP 符号 .

-   **参数**数字 :
    -   `window`:现在前后的30秒步被接受. 使用 `[past, future]` 不同价值; `0` 只接受当前步骤.
-   **回返**数字 : `true` 如果该标志有效; `false` 否则,包括当该令牌丢失或变形或该秘密无效时.
-   **掷出**数字 : `RangeError` 若为 `window` 并非由非负整数所制成,或跨度超过总共98个步骤.

### `verifyTokenOnce(secret: string, token?: string, lastTimeStep?: number | null, window: number | [number, number] = 1): { timeStep: number } | null`

验证像 TOTP 等的标志 `verifyToken`,但也拒绝从 `lastTimeStep` 或更早,所以每个令牌只接受一次.

-   **参数**数字 :
    -   `lastTimeStep`页:1 `timeStep` 由用户上次成功检查返回,或 `null`编号 :`undefined` 如果没有.
    -   `window`: 与单位相同 `verifyToken`。 。 。 .
-   **回返**数字 : `{ timeStep }` 以符号所属的30秒步骤表示,或 `null` 如果该标志被拒绝。 保存 `timeStep` 每次成功后为用户.
-   **掷出**: 与 `verifyToken`外加一个 `RangeError` 若为 `lastTimeStep` 不是一个非负式安全整数.

### `generateHOTPToken(secret: string, counter: number = 0): { token: string } | null`

生成一个计数器的 HOTP 符号 .

-   **回返**数字 : `{ token }`,或 `null` 如果这个秘密无效.
-   **掷出**数字 : `RangeError` 若为 `counter` 不是一个非负式安全整数.

### `verifyHOTPToken(secret: string, token: string | undefined, counter: number): boolean`

核实一个HOTP的标志 与特定的计数器对齐.

-   **回返**数字 : `true` 如果该标志有效; `false` 否则,包括当该令牌丢失或变形或该秘密无效时.
-   **掷出**数字 : `RangeError` 若为 `counter` 不是一个非负式安全整数.

### 类型

`SecretOptions` 财务报告和审定财务报表 `OtpType` (单位:千美元)`"TOTP" | "HOTP"`)为 TypeScript 用户导出.

## 安全说明

-   `verifyToken` 在窗口内时再次接受相同的同物。 屏蔽重放, 使用 `verifyTokenOnce`,包括确认入学的支票,并保存返回的 `timeStep` 只有它向前移动。 在单个语句中做到这一点,并将零更新行作为失败的登录处理,因此两个具有同义的同步请求不能同时成功:
    
    ```sql
    UPDATE users SET last_time_step = $step
    WHERE id = $id AND (last_time_step IS NULL OR last_time_step < $step);
    ```
    
    对HOTP来说,同样推进计数器: `UPDATE users SET counter = counter + 1 WHERE id = $id AND counter = $counter`。 。 。 .
    
-   限制用户可以做多少次验证尝试 .
    
-   保持保密 休息.
    

## 从 0.x 升级

-   HOTP令牌现在跟随RFC 4226并匹配认证器应用,因此它们与所出自0.x的令牌不同.
-   `verifyToken` 财务报告和审定财务报表 `verifyHOTPToken` 返回时 `false` 改为 `null` 当它不见了.
-   `verifyToken` 默认接受前后的一步(30秒),而不是四步.
-   `verifyHOTPToken` 需要的计数器 不再使用 `window` 论点,从未产生任何效果.
-   秘密必须是至少80个比特的犬类基础32. 0.x接受的秘密,比如有空间的秘密,额外 `=` padding 或非 0 未使用的后导位, 现在让生成函数返回 `null` 函数返回 `false`。 。 。 .
-   `numberOfSecretBytes` 必须是至少 `16`。无效类型、计数器和窗口.
-   URI带标准 `issuer` 参数代替 `name`。 。 。 .
-   只有包入口才能被导入:深入口,例如 `2fa-node/dist/secret.js` 没有工作.
-   需要20.19节节点或以后.
-   许可证由MIT改为MPL-2.0.

## 依赖关系

-   [atplib 函数](https://www.npmjs.com/package/otplib) - 用于生成和验证一次性密码的图书馆.
-   [qrcode 码](https://www.npmjs.com/package/qrcode) - 一个生成QR代码的库.

## 许可证

该项目根据Mozilla公共许可证2.0获得许可——见 [利比里亚](https://npmcn.com/package/2fa-node/LICENSE.md) 详细文件.

## 常见问题

### 2fa-node 是什么？

网易 2-Factor 集成为节点\.js

### 如何安装 2fa-node？

在项目目录运行 npm install 2fa-node，或使用 pnpm add / yarn add / bun add。

### 2fa-node 支持 TypeScript 吗？

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

### 2fa-node 支持 ESM 还是 CommonJS？

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

### 2fa-node 需要什么版本的 Node\.js？

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

### 2fa-node 可以商用吗？

2fa-node 使用 MPL-2\.0 许可。弱 Copyleft：可以商用，也可以和闭源代码一起使用；但如果分发时修改了 MPL 授权的文件，这些文件的修改需以 MPL 开源。以上为概括，不构成法律意见，请以许可原文为准。

### 2fa-node 的下载量有多少？

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

### 2fa-node 还在维护吗？

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

