feat(api): API Key + Redis 限流 + 用量统计 (M5a) #7

Merged
lixu merged 1 commits from devin/1781943842-m5a-api-key-ratelimit into main 2026-06-20 16:27:14 +08:00
Owner

Summary

为公开只读 API 增加一层可选 API Key:持 Key 调用可获得更高的每分钟速率上限并归属用量;匿名调用仍然允许,按客户端 IP 走较低额度(默认 60/min)。API 定位不变——免费、只读、无交易端点。

公开服务对 PostgreSQL 仍保持只读:Key 校验只做 SELECT,所有计数(限流窗口 + 用量)都落在 Redis;签发/吊销由后台(admin,本就有写权限)完成。Redis 不可用时全部 fail-open(放行 + 用量显示为 0)。

主要改动

  • 迁移 0008_api_keyapi_key 表只存 key_hash(sha256) + 展示用 key_prefix,明文仅创建时返回一次;含 tier / rate_limit_per_min / revoked_at
  • apikey:生成 og_live_<random> Key + sha256 哈希。
  • ratelimit:Redis 固定窗口限流 + 按 key 的 total/today/last_used 用量;未配置/不可达均 fail-open。
  • 公开 API 中间件/api/v1):读取 X-API-KeyAuthorization: Bearer og_...;非法/吊销→401;每个响应回写 X-RateLimit-Limit/Remaining/Reset;超额→429+Retry-After;匿名按 IP、持 Key 按 key-id 各自限流。
  • 后台GET/POST/DELETE /ping/api/keys 签发/列表(含用量)/吊销 + 运营后台「API 密钥」标签页。

测试

本地 docker postgres+redis:迁移 up/down-all/up 可逆;go vet/gofmt/go test ./... 全过。新增 apikey/ratelimit/handler 中间件单测(依赖 Redis 的用例在无 Redis 环境自动 skip)。真实 HTTP 烟测 200/429/401 + 各响应头已验证。后台前端 npm run build 通过。

## Summary 为公开只读 API 增加一层**可选** API Key:持 Key 调用可获得更高的每分钟速率上限并归属用量;匿名调用仍然允许,按客户端 IP 走较低额度(默认 60/min)。API 定位不变——免费、只读、无交易端点。 公开服务对 PostgreSQL 仍保持只读:Key 校验只做 `SELECT`,所有计数(限流窗口 + 用量)都落在 Redis;签发/吊销由后台(admin,本就有写权限)完成。Redis 不可用时**全部 fail-open**(放行 + 用量显示为 0)。 ## 主要改动 - **迁移 `0008_api_key`**:`api_key` 表只存 `key_hash`(sha256) + 展示用 `key_prefix`,明文仅创建时返回一次;含 `tier` / `rate_limit_per_min` / `revoked_at`。 - **`apikey` 包**:生成 `og_live_<random>` Key + sha256 哈希。 - **`ratelimit` 包**:Redis 固定窗口限流 + 按 key 的 `total/today/last_used` 用量;未配置/不可达均 fail-open。 - **公开 API 中间件**(`/api/v1`):读取 `X-API-Key` 或 `Authorization: Bearer og_...`;非法/吊销→`401`;每个响应回写 `X-RateLimit-Limit/Remaining/Reset`;超额→`429`+`Retry-After`;匿名按 IP、持 Key 按 key-id 各自限流。 - **后台**:`GET/POST/DELETE /ping/api/keys` 签发/列表(含用量)/吊销 + 运营后台「API 密钥」标签页。 ## 测试 本地 docker postgres+redis:迁移 up/down-all/up 可逆;`go vet`/`gofmt`/`go test ./...` 全过。新增 `apikey`/`ratelimit`/`handler` 中间件单测(依赖 Redis 的用例在无 Redis 环境自动 skip)。真实 HTTP 烟测 200/429/401 + 各响应头已验证。后台前端 `npm run build` 通过。
lixu added 1 commit 2026-06-20 16:25:50 +08:00
feat(api): API keys + Redis rate limiting + usage stats
CI / Python (ingestion) (pull_request) Successful in 12s
CI / Migrations (postgres) (pull_request) Successful in 24s
CI / Go (api) (pull_request) Successful in 53s
2820823b36
Add an optional API-key layer to the public read-only API. Keys grant
higher per-minute rate limits and attribute usage; anonymous callers are
still allowed at a lower IP-based budget.

- migration 0008_api_key: api_key table (sha256 hash only, plaintext shown once)
- apikey pkg: key generation + hashing
- ratelimit pkg: Redis fixed-window limiter + per-key usage counters; fails open
- public API middleware: X-API-Key / Bearer auth, X-RateLimit-* headers, 429+Retry-After
- admin: issue/list/revoke keys + usage view (API + UI tab)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
lixu merged commit cf255e2380 into main 2026-06-20 16:27:14 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lixu/goods#7