基于 Cloudflare Workers + KV 的云端 2FA 认证器
Find a file
LiuHao 9d3f1e8303 imp - 使用原生 ARM runner 替代 QEMU 模拟构建,解决多架构镜像构建超时问题
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:58:54 +08:00
.github/workflows imp - 使用原生 ARM runner 替代 QEMU 模拟构建,解决多架构镜像构建超时问题 2026-04-09 14:58:54 +08:00
public imp - 优化卡片点击复制交互,消除按压弹跳动画 2026-04-09 10:48:31 +08:00
src add - PWA 支持和离线数据缓存功能 2026-01-15 10:37:19 +08:00
.dockerignore add - Docker 部署支持 2026-01-14 14:46:54 +08:00
.gitignore imp - 优化卡片点击复制交互,消除按压弹跳动画 2026-04-09 10:48:31 +08:00
docker-compose.yml add - PWA 支持和离线数据缓存功能 2026-01-15 10:37:19 +08:00
Dockerfile add - Docker 部署支持 2026-01-14 14:46:54 +08:00
LICENSE Add MIT License to the project 2026-01-09 11:26:45 +08:00
package.json add - Docker 部署支持 2026-01-14 14:46:54 +08:00
README.md imp - 更新文档说明 PWA 和离线功能 2026-01-15 10:41:51 +08:00
README_EN.md imp - 更新文档说明 PWA 和离线功能 2026-01-15 10:41:51 +08:00
worker.js imp - 优化静态资源托管和提升 PBKDF2 安全性 2026-01-09 14:25:37 +08:00
wrangler.toml add - GitHub Actions 一键部署支持 2026-01-14 17:03:49 +08:00

2FA Authenticator

中文文档

A cloud-based 2FA authenticator supporting both Cloudflare Workers and Docker deployment.

Features

  • TOTP Generation: Compatible with Google Authenticator, Authy, and other standard TOTP protocols
  • Cloud Sync: Data stored in Cloudflare KV, accessible across devices
  • End-to-End Encryption: AES-256-GCM encryption, server only stores ciphertext
  • Zero Registration: No email/phone required, create account with just a master password
  • PWA Support: Install to desktop/home screen for native app experience
  • Offline Access: Full offline support after first login, data cached for 7 days
  • QR Code Scanning: Support camera scanning, image upload, and clipboard paste to recognize QR codes
  • Import/Export: JSON format backup support for data migration and local backup

Architecture

Two deployment methods supported:

Cloudflare Workers Deployment:

Browser <--HTTPS--> Cloudflare Worker <--KV API--> KV Storage

Docker Deployment:

Browser <--HTTP/HTTPS--> Express Server <--SQLite--> Local Database

Security Design:

Aspect Measure
Data Encryption AES-256-GCM, encrypted on client before transmission
Key Derivation PBKDF2-SHA256, 600,000 iterations
User Identification Password hash (PBKDF2)

Deployment Guide

Prerequisites: Install Docker

Using Docker Run

docker run -d \
  --name 2fa-auth \
  -p 3000:3000 \
  -v 2fa-data:/app/data \
  l981244680/2fa:latest

# Visit http://localhost:3000

Using Docker Compose

Create a docker-compose.yml file:

services:
  2fa:
    image: l981244680/2fa:latest
    container_name: 2fa-authenticator
    ports:
      - "3000:3000"
    volumes:
      - ./data:/app/data
    restart: unless-stopped

Then run:

docker compose up -d

Environment Variables

Variable Default Description
PORT 3000 HTTP service port
DB_PATH /app/data/2fa.db SQLite database path

Method 2: Cloudflare Workers Deployment

Prerequisites

Step 1: Install Wrangler CLI

npm install -g wrangler

Step 2: Login to Cloudflare

wrangler login

Step 3: KV Namespace (Optional)

If wrangler.toml only sets binding (no id), wrangler will auto-provision (or reuse) the KV namespace on the first wrangler deploy, and subsequent deploys will still bind to the same KV. So you can skip this step by default.

If you want to create it manually (for example, to pin/reuse an existing KV), run:

# Navigate to project directory
cd 2fa

# Create production KV
wrangler kv namespace create DATA_KV
# Output like: { binding = "DATA_KV", id = "xxxxxxxxxxxx" }

# Create preview KV (Optional)
wrangler kv namespace create DATA_KV --preview
# Output like: { binding = "DATA_KV", preview_id = "yyyyyyyyyyyy" }

Step 4: Configure wrangler.toml

  • Auto provisioning: keep [[kv_namespaces]] with only binding and run wrangler deploy; Wrangler will auto-provision/reuse KV (and won't modify wrangler.toml).
  • Manual: fill the id / preview_id from the previous step into wrangler.toml:
name = "2fa-sync"
main = "worker.js"
compatibility_date = "2024-01-01"
assets = { directory = "./public" }

[[kv_namespaces]]
binding = "DATA_KV"
id = "xxxxxxxxxxxx"        # Replace with your id
preview_id = "yyyyyyyyyyyy" # Replace with your preview_id

Step 5: Local Testing (Optional)

wrangler dev
# Visit http://localhost:8787

Step 6: Deploy

wrangler deploy
# Output like: Published 2fa-sync (https://2fa-sync.xxx.workers.dev)

After deployment, visit the output URL to start using.

GitHub Actions Auto Deploy (Optional)

This repository includes an automatic deployment workflow for the Cloudflare Worker:

  • Deploy Cloudflare Worker: .github/workflows/deploy-worker.yml — deploys the Worker on push to main or via manual dispatch. Requires the repository secrets CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID.

Usage Guide

First Time Setup (Create Account)

  1. Visit the deployed URL
  2. Click "First time? Create account"
  3. Set a master password (at least 4 characters)
  4. Confirm password and click "Set Password"

Login

  1. Enter master password
  2. Click "Unlock"

Add 2FA Key

Click the "+" button in the top right, three methods available:

Manual Input:

  1. Enter a name (e.g., GitHub)
  2. Enter the Base32 format secret key
  3. Click "Add"

Scan QR Code:

  1. Switch to "Scan" tab
  2. Click "Start Camera"
  3. Point the QR code at the camera, auto-fills when recognized

Upload Image:

  1. Switch to "Upload" tab
  2. Click to select, drag and drop, or paste a screenshot
  3. Auto-fills when recognized

Use Verification Code

  • Click the code to copy to clipboard
  • The ring on the right shows remaining valid time (30-second cycle)

Logout

Click the logout button in the top left to clear current session and return to login page.

Import/Export

Export Backup:

  1. After login, click the "Export" button at the bottom of the page
  2. Download the JSON format backup file (stored in plaintext, keep it safe)

Import Backup:

  1. Click the "Import" button at the bottom of the page
  2. Select a previously exported JSON file
  3. Duplicate keys (same name) will be skipped, existing data preserved, only new keys imported

Important Notes

  1. Password Cannot Be Recovered: Forgetting password means losing all data - remember your master password
  2. Password = Account: Same password = same account, use the same password on different devices to sync data
  3. Session Expiry: Session expires when browser tab is closed, password required to login again
  4. Offline Mode: First login requires internet, then works offline (cache valid for 7 days)
  5. Data Sync: Offline changes sync automatically when online; conflicts prompt user to choose

Project Structure

2fa/
├── .github/
│   └── workflows/
│       ├── deploy-worker.yml   # Deploy Cloudflare Worker
│       └── docker-publish.yml  # Build/push Docker image
├── public/
│   ├── icons/           # PWA icons
│   ├── index.html       # Frontend
│   ├── manifest.json    # PWA manifest
│   └── service-worker.js # Service Worker (offline cache)
├── src/
│   └── server.js        # Express server for Docker deployment
├── worker.js            # Cloudflare Worker
├── wrangler.toml        # Wrangler configuration
├── Dockerfile           # Docker image definition
├── docker-compose.yml   # Docker Compose configuration
├── package.json         # npm dependencies
└── README.md            # Documentation

License

MIT