【n8n教程】:TOTP节点,生成双因素认证密码

什么是TOTP?为什么需要它?

在数字时代,仅用密码保护账户已经不够安全。**TOTP(Time-based One-Time Password)是一种基于时间的一次性密码算法,也称为双因素认证(2FA)**的核心技术。

简单来说,TOTP通过将当前时间和一个共享密钥结合起来,使用HMAC-SHA-1等密码算法生成一个6位数字的验证码。这个验证码每30秒自动更新一次,无法被拦截或重复使用,大幅提升了账户安全性。

TOTP的应用场景包括:

TOTP的工作原理

TOTP认证过程分为三个阶段:

1. 密钥共享阶段

用户和服务器通过安全通道共享一个密钥(Secret Key)。这个密钥通常以二维码的形式提供,用户扫描二维码后,验证器应用(如Google Authenticator)就能保存这个密钥。

2. 验证码生成阶段

客户端和服务器都基于以下公式独立计算验证码:


    
    
    
  TC = floor((当前Unix时间戳 - T0) / TS)
TOTP = HMAC-SHA-1(密钥, TC)
验证码 = TOTP mod 10^6(取最后6位数字)

其中:

由于两端的时钟基本同步,在同一个30秒时间窗口内,计算出的验证码完全相同。

3. 验证阶段

用户将生成的验证码输入到登录界面,服务器验证该码是否与本地计算的值匹配。为了防止网络延迟和时钟偏差,大多数服务器会接受前一个时间窗口和后一个时间窗口的验证码。

n8n TOTP节点概述

n8n作为强大的工作流自动化平台,内置了TOTP节点,让开发者能轻松在自动化流程中集成两因素认证功能。

TOTP节点的核心功能

n8n的TOTP节点当前支持**"生成密钥"**操作,具体功能包括:

功能项说明
操作类型生成TOTP密钥(Generate Secret)
输入无需特殊输入,从TOTP凭证中读取配置
输出生成的验证码、剩余有效时间、二维码等
算法支持SHA-1(默认)、SHA-256、SHA-512
位数默认6位,可自定义为4-8位
时间步长默认30秒,可自定义

TOTP节点的参数说明

凭证配置

算法选项(Algorithm)

TOTP支持多种HMAC哈希算法:

生成位数(Digits)

时间周期(Period)

手把手搭建TOTP认证工作流

第一步:准备TOTP凭证

  1. 1. 登录n8n并进入工作流编辑界面
  2. 2. 点击右上角**"Credentials"**按钮
  3. 3. 选择**"Create New Credential"** → "TOTP"
  4. 4. 填写凭证信息:
    • Secret:输入Base32编码的密钥(可从二维码提取)
    • Label:输入应用名称或账户标识

获取Secret的方法:

第二步:创建工作流节点

节点1:开始(Start)

节点2:TOTP节点(生成验证码)

配置完成后,该节点输出内容包括:


    
    
    
  {
  "token"
: "123456",           // 当前生成的验证码
  "secondsRemaining"
: 18,      // 该验证码的剩余有效时间(秒)
  "secret"
: "BVDRSBXQB2ZEL5HE"  // 使用的密钥
}

节点3:处理数据(Code/Function Node)

使用JavaScript代码处理TOTP节点的输出,提取关键信息:


    
    
    
  // 接收TOTP数据并格式化输出
const
 totpResult = items[0].json;

return
 {
  json
: {
    status
: "验证码已生成",
    code
: totpResult.token,
    validTime
: totpResult.secondsRemaining + "秒内有效",
    timestamp
: new Date().toISOString(),
    message
: "请在30秒内使用此验证码进行认证"
  }
};

节点4:验证或存储(HTTP Request/Database Node)

根据需要配置:

第三步:连接节点和测试

  1. 1. 连接节点:从Start → TOTP → 处理 → 输出
  2. 2. **点击"Test Workflow"**进行测试
  3. 3. 观察输出结果,验证验证码是否正确生成
  4. 4. 可使用Google Authenticator等应用扫描输出的二维码验证

完整可执行工作流代码

以下是一个完整的n8n TOTP工作流JSON代码,包括所有节点和连接配置。可以直接导入到n8n中使用:


    
    
    
  {
  "name"
: "TOTP两因素认证工作流示例",
  "description"
: "完整的n8n TOTP节点使用示例 - 展示如何生成和验证时间密码",
  "nodes"
: [
    {

      "parameters"
: {},
      "id"
: "4b36c92d-4c8e-44f6-8f31-7e6e8b8c9d3a",
      "name"
: "开始",
      "type"
: "n8n-nodes-base.start",
      "typeVersion"
: 1,
      "position"
: [
        250
,
        300

      ]

    }
,
    {

      "parameters"
: {
        "resource"
: "secret",
        "operation"
: "generateSecret"
      }
,
      "id"
: "5c47d03e-5d9f-55g7-9g42-8f7f9c9d0e4b",
      "name"
: "生成TOTP密钥",
      "type"
: "n8n-nodes-base.totp",
      "typeVersion"
: 1,
      "position"
: [
        450
,
        300

      ]

    }
,
    {

      "parameters"
: {
        "functionCode"
: "// 接收TOTP密钥和当前时间\nconst totpData = items[0].json;\n\nreturn {\n  json: {\n    secret: totpData.secret,\n    label: totpData.label || 'MyApp',\n    qrCode: totpData.qrCode,\n    setupTime: new Date().toISOString(),\n    message: 'TOTP密钥已生成,请使用Google Authenticator等应用扫描二维码'\n  }\n};"
      }
,
      "id"
: "6d58e14f-6e0g-66h8-0h53-9g8g0d0e1f5c",
      "name"
: "处理密钥信息",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [
        650
,
        300

      ]

    }
,
    {

      "parameters"
: {
        "method"
: "POST",
        "url"
: "https://webhook.site/unique-id",
        "sendHeaders"
: true,
        "headerParameters"
: {
          "parameters"
: [
            {

              "name"
: "Content-Type",
              "value"
: "application/json"
            }

          ]

        }
,
        "bodyParametersJson"
: "={\n  'secret': '{{ $node[\"处理密钥信息\"].json.secret }}',\n  'timestamp': '{{ $node[\"处理密钥信息\"].json.setupTime }}',\n  'status': 'TOTP密钥已成功生成'\n}"
      }
,
      "id"
: "7e69f25g-7f1h-77i9-1i64-0h9h1e1f2g6d",
      "name"
: "保存到数据库",
      "type"
: "n8n-nodes-base.httpRequest",
      "typeVersion"
: 4.1,
      "position"
: [
        850
,
        300

      ]

    }
,
    {

      "parameters"
: {
        "jsCode"
: "// 输出最终结果\nreturn [\n  {\n    json: {\n      status: '成功',\n      message: 'TOTP工作流执行完成',\n      output: $node['保存到数据库'].json\n    }\n  }\n];"
      }
,
      "id"
: "8f70g36h-8g2i-88j0-2j75-1i0i2f2g3h7e",
      "name"
: "输出结果",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [
        1050
,
        300

      ]

    }

  ]
,
  "connections"
: {
    "开始"
: {
      "main"
: [
        [

          {

            "node"
: "生成TOTP密钥",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "生成TOTP密钥"
: {
      "main"
: [
        [

          {

            "node"
: "处理密钥信息",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "处理密钥信息"
: {
      "main"
: [
        [

          {

            "node"
: "保存到数据库",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "保存到数据库"
: {
      "main"
: [
        [

          {

            "node"
: "输出结果",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }
,
  "active"
: false,
  "settings"
: {
    "executionOrder"
: "v1"
  }
,
  "versionId"
: "1.0"
}

导入工作流步骤:

  1. 1. 复制上面的JSON代码
  2. 2. 在n8n中新建工作流
  3. 3. 右上角菜单 → "Import from URL""Paste Workflow JSON"
  4. 4. 粘贴代码后点击导入
  5. 5. 根据实际需求修改节点参数和凭证

实战案例:用户2FA登录流程

场景描述

构建一个完整的用户双因素认证登录系统,包括:

  1. 1. 用户输入用户名和密码
  2. 2. 验证密码正确性
  3. 3. 调用TOTP节点生成验证码
  4. 4. 通过邮件或短信发送验证码
  5. 5. 用户输入验证码后完成登录

完整工作流设计


    
    
    
  [用户登录表单] 
    ↓
[验证用户名密码] 
    ↓
[TOTP节点生成验证码] 
    ↓
[发送验证码到邮箱/短信] 
    ↓
[等待用户输入验证码]
    ↓
[验证验证码有效性] 
    ↓
[返回登录成功/失败]

关键代码片段

验证验证码有效性:


    
    
    
  // 获取用户输入的验证码和系统生成的验证码
const
 userCode = $node['用户输入'].json.code;
const
 systemCode = $node['TOTP节点生成验证码'].json.token;
const
 secondsRemaining = $node['TOTP节点生成验证码'].json.secondsRemaining;

// 验证逻辑

if
 (userCode === systemCode && secondsRemaining > 0) {
  return
 {
    json
: {
      status
: "success",
      message
: "验证通过,登录成功",
      userId
: $node['用户数据'].json.userId
    }
  };
} else {
  return
 {
    json
: {
      status
: "failed",
      message
: "验证码错误或已过期,请重新登录"
    }
  };
}

常见问题解答

Q1: TOTP验证码总是显示过期?

A: 确保n8n所在服务器和用户客户端的系统时间同步。大多数系统会接受±1个时间窗口(±30秒)的验证码,如果偏差太大会导致验证失败。

Q2: 如何支持更强的加密算法?

A: 在TOTP节点的算法参数中选择SHA-256或SHA-512。但要注意,某些旧的验证器应用可能不支持这些算法。

Q3: 可以自定义验证码长度吗?

A: 可以。在TOTP节点的位数参数中修改,支持4-8位。但建议保留默认的6位,确保兼容性。

Q4: 如何在离线环境中生成TOTP?

A: TOTP是基于本地时间计算的,不需要网络连接。只要设备时间准确,即可离线生成。

Q5: TOTP凭证泄露了怎么办?

A: 立即更换密钥。联系服务方重新生成TOTP二维码,并在所有验证器应用中删除旧凭证。

安全最佳实践

  1. 1. 密钥管理
    • • 将TOTP密钥安全地存储在加密的数据库中
    • • 不要在日志或错误消息中暴露密钥
    • • 定期轮换密钥
  2. 2. 验证码使用
    • • 每个验证码仅能使用一次
    • • 实施验证码超时机制
    • • 限制验证尝试次数,防止暴力破解
  3. 3. 时间同步
    • • 定期检查系统时间准确性
    • • 实施NTP时间同步
    • • 在验证时允许时间偏差窗口
  4. 4. 备用方案
    • • 提供备用验证方式(恢复码、备用邮箱)
    • • 为用户保存恢复码,以防设备丢失

总结

n8n的TOTP节点为开发者提供了一个简单而强大的工具,用于在自动化工作流中集成双因素认证。通过本教程,你已经掌握了:

✅ TOTP的基本原理和工作机制
✅ n8n TOTP节点的完整配置方法
✅ 从零开始构建2FA认证工作流
✅ 实战案例和代码示例
✅ 常见问题解决和安全最佳实践

现在你可以自信地在自己的项目中使用TOTP节点,为用户账户增加一层强大的安全保护!


引用链接

[1] 官方文档: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.totp/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#