logo
0
0
WeChat Login
ForkfromPhira-download/eo-kv, aheadmain2 commits

KV 存储管理 API

基于 EdgeOne Edge Function 的 KV 存储管理系统,提供完整的读写删操作接口,支持多命名空间、多种鉴权方式(长期令牌和 TOTP 2FA)。

目录

1. 快速开始

1.1 前置要求

  • EdgeOne 账户和项目
  • wrangler CLI 工具
  • Node.js 环境

1.2 环境变量配置

参照.env的内容填写完毕添加到Edgeone的环境变量中即可

# 必需:KV 命名空间绑定名(必须与EO KV的命名空间 一致) KV_NAMESPACE_BINDING=xxxxxx # 可选:长期管理令牌(用于写操作鉴权) KV_ADMIN_TOKEN=your_secret_token_here_at_least_32_characters # 可选:TOTP 2FA 密钥(Base32 编码) # 注意:至少需要配置上面两个中的一个 TOTP_SECRET=your_totp_secret

1.3 生成安全的令牌和密钥(可跳过)

生成长期令牌

# Linux/Mac openssl rand -base64 32 # Windows (PowerShell) $bytes = [byte[]]::new(32) $random = [System.Security.Cryptography.RandomNumberGenerator]::Create() $random.GetBytes($bytes) [Convert]::ToBase64String($bytes)

生成 TOTP 密钥

# Linux/Mac openssl rand -base64 20 | base32 | head -c 32 # Windows (PowerShell) $bytes = [byte[]]::new(15) $random = [System.Security.Cryptography.RandomNumberGenerator]::Create() $random.GetBytes($bytes) # 使用在线 Base32 编码工具或以下命令: # [Convert]::ToBase64String($bytes) | Out-Host

1.4 部署

# 开发环境(使用 .env.local) wrangler dev --env development # 生产环境 wrangler deploy --env production

1.5 推送到 EdgeOne Pages(CNB)

如果你使用 CNB 持续集成发布到 EdgeOne Pages,可按以下步骤配置:

  1. 在腾讯云控制台进入 EdgeOne Pages OpenAPI 页面,创建或获取你的 Pages API Token: https://console.cloud.tencent.com/edgeone/pages?tab=api
  2. 在 CNB 创建密钥仓库,并添加密钥:
  • 键名:EDGEONE_API_TOKEN
  • 键值:上一步获取的 Pages API Token
  1. 打开项目根目录下 .cnb.yml,按注释提示将密钥仓库地址改为你自己的仓库地址。
  2. 提交代码并触发流水线,确认 EdgeOne Pages 发布任务执行成功。

建议:API Token 仅保存在密钥仓库中,不要写入代码或提交到 Git。

2. 环境变量详解

2.1 文件位置

  • .env.example - 配置示例文件(提交到 Git)
  • .env.local - 本地开发配置(不提交,由 .gitignore 保护)
  • .env - 生产配置(不提交,由 .gitignore 保护)

2.2 必需配置

2.2.1 KV_NAMESPACE_BINDING (必需)

  • 类型: 字符串
  • 说明: 指定要使用的 KV 命名空间的绑定变量名
  • 示例: phira_web
  • 验证: 必须与 wrangler.toml 中的 binding 名称完全一致
  • 错误处理: 未配置时返回 500 错误并提示配置说明

示例配置:

# .env.local KV_NAMESPACE_BINDING=phira_web

2.3 鉴权令牌配置(至少配置一个)

2.3.1 方案 A:长期令牌(推荐用于生产环境)

环境变量: KV_ADMIN_TOKEN

  • 类型: 字符串
  • 长度: 至少 32 字符(推荐 64 字符)
  • 说明: 用于写操作(PUT/DELETE)的管理员令牌
  • 生成: 使用强随机数生成器

配置示例:

# .env.local KV_ADMIN_TOKEN=dadwadwadwadwadwa # 特点: # - 固定令牌,长期有效 # - 使用简单 # - 需要定期轮换(建议每 90 天)

2.3.2 方案 B:TOTP 2FA(推荐用于增强安全性)

环境变量: TOTP_SECRET

  • 类型: Base32 编码字符串
  • 长度: 通常 32 字符
  • 说明: 用于生成 TOTP 验证码的密钥
  • 配合: 认证器应用(Google Authenticator、Authy 等)

配置步骤:

  1. 生成 Base32 格式密钥
  2. 在认证器应用中添加密钥(扫描二维码或手动输入)
  3. .env.local 中配置
# .env.local TOTP_SECRET=dwadwadwadwadwadwadawdwa # 特点: # - 每 30 秒变换一次验证码 # - 更加安全 # - 需要认证器应用

2.3.3 方案 C:同时配置两者(最安全)

# .env.local KV_ADMIN_TOKEN=ddawdadwadwadwa TOTP_SECRET=dawdwadwadwadwadwadwadwa # 好处: # - 提供多种认证选择 # - 增强安全性 # - 易于令牌轮换

3. API 接口

3.1 列出所有键 (无需鉴权)

GET /kv-admin/list

查询参数:

  • prefix (可选) - 键名前缀过滤
  • limit (可选) - 返回数量限制,默认 256,最大 256
  • cursor (可选) - 分页游标

响应示例:

{ "complete": true, "cursor": null, "keys": [ {"key": "faq"}, {"key": "announcement"}, {"key": "server"} ] }

3.2 读取键值内容 (无需鉴权)

GET /kv-admin/get?key=test_key&type=text

查询参数:

  • key (必需) - 要读取的键名
  • type (可选) - 返回数据类型
    • text (默认) - 文本格式
    • json - JSON 对象格式
    • arrayBuffer - 二进制数据(返回 base64 编码)
    • stream - 流数据(转换为文本)

响应示例(文本):

{ "key": "test_key", "value": "test_value", "type": "text", "size": 10 }

响应示例(JSON):

{ "key": "config", "value": { "setting1": "value1", "setting2": "value2" }, "type": "json", "size": 45 }

3.3 写入/更新键值对 (需要鉴权)

PUT /kv-admin/put Content-Type: application/json Authorization: Bearer <token> { "key": "test_key", "value": "test_value" }

鉴权方式:

# 方式 1:Authorization Header(推荐) Authorization: Bearer your_secret_token_here # 方式 2:Query Parameter ?token=your_secret_token_here

响应示例:

{ "success": true, "message": "Key 'test_key' updated successfully" }

3.4 删除键值对 (需要鉴权)

DELETE /kv-admin/delete Content-Type: application/json Authorization: Bearer <token> { "key": "test_key" }

响应示例:

{ "success": true, "message": "Key 'test_key' deleted successfully" }

4. 鉴权详解

4.1 支持的令牌类型

令牌类型格式有效期来源
长期令牌任意字符串长期有效KV_ADMIN_TOKEN
TOTP码6 位数字90 秒,包含前后空窗期TOTP_SECRET

4.2 鉴权示例

使用长期令牌:

curl -X PUT "https://your-domain.com/kv-admin/put" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer a7f3K9xR2mQ8nB4pL6vJ5wC+D/E=" \ -d '{"key": "test", "value": "hello"}'

使用 TOTP 验证码(从认证器获取):

curl -X PUT "https://your-domain.com/kv-admin/put" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 123456" \ -d '{"key": "test", "value": "hello"}' # 或使用查询参数 curl -X PUT "https://your-domain.com/kv-admin/put?token=123456" \ -H "Content-Type: application/json" \ -d '{"key": "test", "value": "hello"}'

4.3 认证器应用推荐

  • Google Authenticator (iOS/Android)
  • Microsoft Authenticator (iOS/Android)
  • Authy (iOS/Android/Desktop)
  • 1Password (iOS/Android/Desktop)

5. 使用示例

5.1 curl 命令示例

列出所有键:

curl -X GET "https://your-domain.com/kv-admin/list"

列出前缀为 "config" 的键:

curl -X GET "https://your-domain.com/kv-admin/list?prefix=config&limit=50"

读取单个键值:

curl -X GET "https://your-domain.com/kv-admin/get?key=announcement"

读取 JSON 格式数据:

curl -X GET "https://your-domain.com/kv-admin/get?key=config&type=json"

使用长期令牌创建/更新:

curl -X PUT "https://your-domain.com/kv-admin/put" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your_secret_token_here" \ -d '{"key": "news", "value": "Hello World"}'

使用 TOTP 删除:

curl -X DELETE "https://your-domain.com/kv-admin/delete" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 123456" \ -d '{"key": "old_news"}'

5.2 JavaScript 示例

const API_BASE = 'https://your-domain.com/kv-admin'; const ADMIN_TOKEN = 'your_secret_token_here'; // 或 6 位 TOTP 码 // 列出所有键 async function listKeys(prefix = '', limit = 256) { const url = new URL(`${API_BASE}/list`); if (prefix) url.searchParams.set('prefix', prefix); url.searchParams.set('limit', limit); const response = await fetch(url); return await response.json(); } // 读取键值 async function getKey(key, type = 'text') { const url = new URL(`${API_BASE}/get`); url.searchParams.set('key', key); url.searchParams.set('type', type); const response = await fetch(url); return await response.json(); } // 写入/更新键值 async function putKey(key, value, token = ADMIN_TOKEN) { const response = await fetch(`${API_BASE}/put`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ key, value }) }); return await response.json(); } // 删除键值 async function deleteKey(key, token = ADMIN_TOKEN) { const response = await fetch(`${API_BASE}/delete`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ key }) }); return await response.json(); } // 使用示例 (async () => { // 列出所有键 const keys = await listKeys(); console.log('所有键:', keys); // 读取特定键 const data = await getKey('announcement', 'json'); console.log('公告数据:', data); // 写入新键 const result = await putKey('test', 'Hello World'); console.log('写入结果:', result); })();

6. 错误响应

500 配置错误

KV 命名空间未配置:

{ "error": "Configuration error", "message": "Environment variable \"KV_NAMESPACE_BINDING\" is not configured. Please set it to the name of your KV namespace binding (e.g., \"phira_web\")" }

KV 绑定不存在:

{ "error": "KV namespace not found", "message": "KV binding 'phira_web' specified in KV_NAMESPACE_BINDING is not bound in wrangler.toml. Please check your configuration." }

401 未授权

{ "error": "Unauthorized", "message": "Valid admin token required for write operations" }

400 请求错误

{ "error": "Key and value are required" }

404 键不存在

{ "error": "Key not found", "message": "Key 'test_key' does not exist in KV storage" }

405 方法不允许

{ "error": "Method not allowed" }

7. 限制说明

项目限制
键名规则只能包含字母、数字和下划线
键名长度最大 512 字节
值大小最大 25 MB
分页限制单次最多返回 256 个键
TOTP有效期30 秒,允许前后各 30 秒误差
读操作鉴权无需鉴权
写操作鉴权需要令牌鉴权

8. 安全建议

令牌管理

  1. 长期令牌安全:

    • 使用足够强的随机字符串(至少 32 字符)
    • 定期轮换 KV_ADMIN_TOKEN(建议每 90 天)
    • 不要在代码注释中暴露令牌
    • 限制令牌访问范围(如果可能)
  2. TOTP 安全:

    • 妥善保管生成 TOTP 密钥时的二维码或密钥文本
    • 在认证器应用中启用备份/恢复功能
    • 配置后不要修改密钥(会导致现有验证码失效)
    • 确保服务器时间准确(TOTP 依赖时间同步)

访问控制

  1. 限制管理接口的访问来源(使用 WAF 或网络策略)
  2. 监控写操作日志
  3. 定期审查访问权限
  4. 为不同的服务使用不同的令牌

HTTPS

  • ✅ 生产环境必须使用 HTTPS
  • ❌ 绝不在 HTTP 上传输敏感信息

🚨 常见问题

Q1: 返回 500 "KV namespace not configured"

原因: KV_NAMESPACE_BINDING 环境变量未配置

解决:

# 复制示例文件 cp .env.example .env.local # 编辑 .env.local KV_NAMESPACE_BINDING=xxxxxx

Q2: 返回 500 "KV binding not found"

原因: wrangler.toml 中未绑定指定的 KV 命名空间

解决: 在Edgeone Page绑定就好

Q3: 返回 401 未授权

可能原因:

  • 未配置 KV_ADMIN_TOKENTOTP_SECRET
  • 传入的令牌值错误
  • TOTP 验证码已过期(每 30 秒变换一次)
  • 服务器时间不同步(TOTP)

解决步骤:

  1. 检查 .env.local 是否配置了认证
  2. 确认传入的令牌值正确
  3. 对于 TOTP,确认验证码在 30 秒内(允许前后各 30 秒误差)
  4. 同步服务器时钟

Q4: TOTP 验证一直失败

原因: 通常是服务器时间不同步

解决:

  1. 检查服务器时间是否准确
  2. 同步服务器时钟
  3. 检查认证器应用的时间同步

Q5: 如何生成 TOTP 密钥?

# Linux/Mac openssl rand -base64 20 | base32 | head -c 32 # 或使用 Python python3 -c "import os, base64; print(base64.b32encode(os.urandom(20)).decode())"

Q6: .env 文件被 Git 提交了怎么办?

# 删除 Git 历史中的 .env 文件(使用 git-filter-repo) git filter-repo --path .env --invert-paths # 或添加到 .gitignore 后强制更新 echo ".env" >> .gitignore git rm --cached .env git commit -m "Remove .env from tracking"

📊 配置总结表

环境变量必需类型说明
KV_NAMESPACE_BINDING字符串KV 命名空间绑定名
KV_ADMIN_TOKEN❌*字符串长期管理令牌
TOTP_SECRET❌*Base32TOTP 2FA 密钥

* 至少需要配置其中之一用于鉴权

📁 文件结构

KV存储/ ├── README.md # 本文件 ├── .env.example # 环境变量示例(提交到 Git) ├── .env.local # 本地开发环境(不提交) ├── .gitignore # Git 忽略规则(保护 .env 文件) ├── index.html # 前端管理界面 ├── api/ │ ├── kv/ │ │ └── [key]/ │ │ └── route.ts # Next.js 开发路由 │ └── kv-admin/ │ └── [action]/ │ └── route.ts # Next.js 开发路由 └── functions/ └── api/ ├── kv/ │ └── [key].js # EdgeOne Edge Function └── kv-admin/ └── [action].js # EdgeOne Edge Function

📚 相关资源

📄 许可证

MIT License

🤝 贡献

欢迎提交 Issue 和 Pull Request!


最后更新: 2026年3月19日

版本: 2.1

About

No description, topics, or website provided.
Language
HTML75.9%
JavaScript24.1%