一体化 API 网关 + 控制台。Go 后端(Gin + gRPC)+ Next.js 前端(App Router + shadcn/ui),自带凭据池、邮件验证、Linux.do OAuth2 SSO、配额计费、TOTP 二步验证。
- 统一 REST 网关 — 单进程或多 service 模式,gateway → auth/music/pool/quota/billing/worker gRPC 后端可独立部署
- 凭据池 (encrypted) — KEK + DEK 信封加密,AES-256-GCM with AAD,POOL_KEK_HEX 主密钥派生
- 邮箱注册 + 激活 — SMTP 发码 / 激活链接,双重保险(验证码 + 邮件链接),未配置 SMTP 自动 demote 到 LogSender
- OAuth2 第三方登录 — Linux.do SSO(PKCE S256 + HMAC 签名 state cookie),登录 / 绑定 / 解绑三态决策,token 加密落库
- 配额 / 计费 — PlanQuotaMiddleware 在 gateway 层兜底,business service 内部按 plan + scope 二次校验
- TOTP 二步 —
pquerna/otp+ Redis 重放保护 - 审计日志 — 结构化 JSON,按 type 分文件,每天滚动
- CSRF + Session —
sidhttpOnly cookie +X-CSRF-Token头双校验 - shadcn/ui 控制台 — Next.js 16 App Router + Radix + Tailwind v4
karpov-gateway/
├── gateway/ # Go 后端 (Gin + gRPC)
│ ├── cmd/ # 各 service 入口 (gateway/auth/music/pool/...)
│ ├── internal/ # 业务实现 (private)
│ ├── api/ # protobuf 定义
│ ├── migrations/ # PostgreSQL schema
│ ├── go.mod # Go 模块 (go 1.24+)
│ └── Dockerfile
├── web/ # Next.js 16 前端控制台
│ ├── src/ # App Router pages + components
│ ├── middleware.ts # CSRF / session / CSP nonce
│ ├── package.json # pnpm workspace
│ └── Dockerfile
├── deploy/
│ ├── compose/ # 本地开发 (PG + Redis + pgAdmin)
│ └── compose-prod/ # 生产单机 (gateway + web + PG + Redis 全栈)
└── .github/workflows/ # GitHub Actions CI (lint / test / build / govulncheck / gosec)
| 工具 | 版本 |
|---|---|
| Go | 1.24+ |
| Node.js | 20.11+ |
| pnpm | 9+ |
| Docker | 24+ |
| PostgreSQL | 14+ |
| Redis | 7+ |
cd deploy/compose
cp .env.example .env # 改强密码!
docker compose up -dcd gateway
cp .env.example .env # 与 deploy/compose/.env 的 PG/Redis 密码保持一致
go mod download
go run ./cmd/qqmusic-gateway
# 默认 :8080 (HTTP) + :9000 (gRPC)
# 首次启动会在 stderr 打印一个 superadmin 账号 + 临时密码cd web
cp .env.example .env.local
pnpm install
pnpm dev
# http://localhost:3000cd deploy/compose-prod
cp .env.example .env
# 编辑 .env:填入真域名 / 强密码 / SMTP 凭据 / OAuth client
nano .env
# 生成 KEK
openssl rand -hex 32 # → 写到 POOL_KEK_HEX=
docker compose up -d --build
docker compose logs -f gateway注意事项:
NEXT_PUBLIC_APP_URL改了必须docker compose build --no-cache web,因为它会被 inline 进 client bundle- 反向代理(Nginx/Caddy)后必须开
TRUST_PROXY=true,否则 X-Forwarded-Proto 不生效 - KEK 一旦改变,旧凭据池 / 旧 OAuth token 全部不可读
- 去 https://connect.linux.do 申请应用
- 回调地址填:
https://your-domain/v1/auth/oauth/linuxdo/callback - 把拿到的 client_id / client_secret 写到
.env:OAUTH_LINUXDO_ENABLED=true OAUTH_LINUXDO_CLIENT_ID=... OAUTH_LINUXDO_CLIENT_SECRET=... OAUTH_LINUXDO_MIN_TRUST_LEVEL=1 OAUTH_PUBLIC_BASE=https://your-domain OAUTH_FRONTEND_BASE=https://your-domain - 重启 gateway,登录页 / 注册页会自动出现 "Linux.do 一键登录"
# Go
cd gateway
go vet ./...
go test -race ./...
golangci-lint run --timeout=5m
# Web
cd web
pnpm lint
pnpm typecheck后端:
- gin-gonic/gin — HTTP 框架
- grpc-ecosystem — gRPC + gateway
- jackc/pgx — PostgreSQL 驱动
- redis/go-redis — Redis 客户端
- golang.org/x/oauth2 — OAuth2 / PKCE
- pquerna/otp — TOTP
前端:
- Next.js 16 (App Router + Turbopack)
- shadcn/ui + Radix
- Tailwind CSS v4
- next-auth-csrf edge-safe CSRF
MIT — 见 LICENSE
PR / Issue 欢迎。提 PR 前请:
golangci-lint run+gofmt -l .全绿go test -race ./...全绿- Web 改动跑
pnpm lint && pnpm typecheck - 不要提交
.env/data/.kek或任何包含真实密码的文件
发现安全问题请直接联系 maintainer,不要开 public issue。
Built with ❤️ by MiChongs