topfans/backend/.env.example
zerosaturation 293c7b14ae fix(security): JWT key governance — MustInit fail-fast + atomic.Value
- pkg/jwt: 删 public SetSecret; 加 MustInit(secret string) 启动时强制注入,
  缺/为空/等于弱默认值时返回 error(运行期不可再改); 密钥用 atomic.Value
  存 []byte,所有读走 mustSecret() 原子 Load,消除 SetSecret/ParseToken 并发
  data race(go test -race 零告警)。
- gateway main + auth_provider: 启动时 MustInit 读 JWT_SECRET env,失败 fatal。
- scripts/loadgen/seed/tokens: 同步 MustInit。
- .env.example: JWT_SECRET 改为 ≥32 字节 base64 示例(原为空,被 MustInit
  立即拒);注释提示生产 MUST replace。
- 测试: 4 个 MustInit 行为 + 1 个 50-goroutine race 覆盖。
- 行为变更: 任何 .env 缺 JWT_SECRET 或用占位 secret 的服务,启动会 panic
  (这是 fail-fast 期望行为);其余 4 个 .env 文件占位由 ops 单独轮换。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-23 18:50:12 +08:00

145 lines
6.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ==================== H5 落地页 Base URL ====================
# 分享服务生成的落地页链接前缀 (landingBase + asset_id + from=sharer + s=system_type)
# - 本地开发: http://localhost:5173 (Vite H5 默认端口,可在 .env 覆盖)
# - 生产环境: 由 deploy/envs/asset.env 注入实际域名
# 注意: 与 frontend/.env.production 的 VITE_LANDING_BASE_URL 保持一致
LANDING_BASE_URL=http://localhost:5173
# ==================== Server Configuration ====================
# Gin运行模式: debug, release, test
GIN_MODE=release
# API网关端口
SERVER_PORT=8080
# ==================== JWT Configuration ====================
# JWT 密钥(MustInit 必填,≥32 字节随机;启动期 MustInit 校验)
# 示例: 任意 32+ 字节随机串(可用 `openssl rand -base64 48` 生成)
# 占位示例(本地开发/CI 用,MUST replace in prod): 随机 base64 字符串(48 字节 = 64 base64 字符)
JWT_SECRET=ZGV2X2p3dF9zZWNyZXRfa2V5X3BsYWNlaG9sZGVyX2F1dGhfbmVlZHNfdG9fYmVfMzJfYnl0ZXNfbG9uZw==
# ==================== Dubbo Service URLs ====================
# 各微服务的Dubbo连接地址直连模式
DUBBO_USER_SERVICE_URL=tri://127.0.0.1:20000
DUBBO_SOCIAL_SERVICE_URL=tri://127.0.0.1:20001
DUBBO_ASSET_SERVICE_URL=tri://127.0.0.1:20003
DUBBO_GALLERY_SERVICE_URL=tri://127.0.0.1:20004
DUBBO_ACTIVITY_SERVICE_URL=tri://127.0.0.1:20005
DUBBO_TASK_SERVICE_URL=tri://127.0.0.1:20006
DUBBO_STARBOOK_SERVICE_URL=tri://127.0.0.1:20007
# ==================== Database Configuration ====================
# PostgreSQL数据库配置
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=topfans
# ==================== Redis Configuration ====================
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# ==================== OSS Configuration ====================
# 阿里云OSS配置
OSS_REGION=cn-shanghai
OSS_BUCKET_NAME=your-bucket-name
OSS_STS_ROLE_ARN=acs:ram::1234567890123456:role/your-oss-role-name
OSS_ACCESS_KEY_ID=your-access-key-id
OSS_ACCESS_KEY_SECRET=your-access-key-secret
OSS_AVATAR_DIR=avatar/
OSS_ASSET_DIR=asset/
OSS_TOKEN_EXPIRE_TIME=3600
# ==================== Service Ports ====================
# 各服务端口用于flag参数
# User Service: 20000
# Social Service: 20001
# Asset Service: 20003
# Gallery Service: 20004
# Activity Service: 20005
# ==================== Logging ====================
# 环境: development, production
ENV=development
# 日志级别: debug, info, warn, error
LOG_LEVEL=info
# ==================== MiniMax API Configuration ====================
MINIMAX_API_KEY=
MINIMAX_API_URL=https://api.minimaxi.com/v1/image_generation
# ==================== Segment (镭射卡抠图) ====================
# auto=自部署HTTP(若有)→imageseg→IVPDimageseg=VIAPI SegmentHDBodyivpd=旧版 IVPD SegmentImage
SEGMENT_PROVIDER=imageseg
# 自部署 rembghttp://127.0.0.1:7000/api/remove
SEGMENT_INFERENCE_URL=
# ==================== WebSocket ====================
# AI Chat WebSocket 路径(用于 Nginx 反向代理)
# 完整连接 URL = ws://<host>:<port><WS_AI_CHAT_PATH>?token=Bearer_xxx
# 需与 frontend/.env.{development,production} 的 VITE_WS_AI_CHAT_PATH 保持一致
# Nginx 反代示例:
# location /ai-chat {
# proxy_pass http://gateway:8080;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# }
# WS_AI_CHAT_PATH=/ai-chat
# ==================== Dify AI Workflow ====================
# Dify API 地址(自部署或云服务)
DIFY_API_BASE=http://localhost/v1
# Dify App API Keylaser_card_variants_v1 工作流)
# DIFY_API_KEY=app-tIfFhFwj3xnbRurK1oxxBXnA
# Dify 工作流名称relay-dify 模式时使用的 Dify app用于 prompt 增强)
DIFY_WORKFLOW=laser_prompt_enhancer_v2
# ==================== 镭射卡生成器 ====================
# LASER_GEN_PROVIDER:
# minimax (默认) - 后端直连 MiniMax, 并行 5 variant 生成背景+装饰, 再调 compositor 合成
# dify - 调 Dify laser_card_variants_v1 工作流, 由 Dify 内部分发
# openai - 后端直连 OpenAI /v1/images/edits, 5 路并发 + 直接落 OSS (不调 compositor)
# relay-dify - Dify 增强 prompt → 中转站 edits → 落 OSS单张调试可扩展
LASER_GEN_PROVIDER=openai
# ==================== OpenAI Images API (LASER_GEN_PROVIDER=openai 时使用) ====================
# 必填:OpenAI API Key(去 https://platform.openai.com/api-keys 生成)
OPENAI_API_KEY=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
# 可选:API 端点(默认官方地址;如使用代理或自建兼容服务可改)
OPENAI_BASE_URL=https://api.openai.com/v1
# 可选:模型名(默认 gpt-image-1.5;可选 gpt-image-1 / dall-e-3)
OPENAI_MODEL=gpt-image-1.5
# laser-compositor 内网地址
# 注意7000 端口在 macOS 上被 AirPlay Receiver 占用,因此改用 7002
LASER_COMPOSITOR_URL=http://127.0.0.1:7002
# laser-compositor 监听端口(与 URL 端口一致)
COMPOSITOR_PORT=7002
# ==================== Mobile Push (uniPush) ====================
# 通知服务使用:通知创建后通过 uniCloud sendMessage 云函数触发手机通知栏
# 以下变量由 notificationService 进程读取(见 deploy/envs/notification.env
# 注意:生产 URL 走环境变量注入,不要提交到代码仓库
PUSH_ENABLED=true
PUSH_URL=
PUSH_TIMEOUT_MS=4000
OPENAI_API_KEY=sk-eIOujD5rUugIRIPecFi3I2rFr6Bhxx1jsRzRm6phyNeeKrCI
# 微达API BaseURL必须含 /v1 后缀,代码会拼成 /v1/images/edits
OPENAI_BASE_URL=https://api.weda.cc/v1
# 中转站实际暴露的 image 模型
OPENAI_MODEL=gpt-image-2
# ==================== aichatdify ====================
DIFY_API_KEY=app-aHnBfMeOQp7A9dQneIFPdPaZ
DIFY_API_BASE=http://localhost/v1
DIFY_TIMEOUT_SEC=60
# ==================== 周边防伪验真peripheral_verify====================
# 详见 docs/design/peripheral-verify.md §5.1
# ⚠️ 关键:必须与 TopFans-activity-admin/backend/.env 中的 PERIPHERAL_SECRET_KEY 完全一致
# 用于 Go gateway 验真接口的 HMAC 签名校验
# 决策 #9:永不轮换,仅在泄露时更换
# 生成命令:python3 -c "import secrets; print(secrets.token_hex(64))"
SECRET_KEY=