# 数字我 / Digital Me — 生产环境配置 Checklist > 逐项对照 `digital-me-backend/.env`。分四档:🔴 不设=有洞/起不来 · 🟠 强烈建议 · 🟡 按功能可选 · ⚪ 可留默认。 --- ## 🔴 0. 总开关(漏了这个,前面所有安全修复都白做) - [ ] **`NODE_ENV=production`** 这是本次安全修复的**总开关**。不设它(默认 development)会导致: - 忘记密码 / 短信验证码 **明文回传**(任意账户可被接管) - 商店 stub 通道 **免支付开通 + 冒充登录** - 微信 `mock-scan` 后门 **开着** - `assertProdConfig` 直接跳过 → **默认 JWT 密钥都不会被拦** > 部署后务必确认进程真的读到了 `production`:启动日志应是 `on :3701 (production)`。 ## 🔴 1. 起不来 / 必设 - [ ] **`JWT_SECRET`** = 强随机值(≠ `change-me-in-prod`)。生产下不设,服务**拒绝启动**(fail-fast,符合预期)。 生成:`openssl rand -hex 32` 或 `node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"` - [ ] **`MONGO_URI`** = 你的生产 Mongo(默认 `mongodb://localhost:27017` 仅本机可用)。 - [ ] **`MONGO_DB`** = `digital_me`(独立库,别和别的产品共用)。 - [ ] **`CORS_ORIGINS`** = 前端真实域名(如 `https://digitalme.invoratec.cn`)。不对会导致前端跨域被拦。 - [ ] **`PUBLIC_URL`** = 本 API 的公网地址(如 `https://digitalme-api.invoratec.cn`)。捏脸/口播视频靠它被 DashScope 回拉素材,必须公网可达。 ## 🟠 2. 强烈建议(安全 / 生产质量) - [ ] **`DATA_ENC_KEY`** = 任意强随机串。不设 → 访客聊天记录**明文入库**(`assertProdConfig` 只 warn 不拦)。 - [ ] **`SUPER_ADMIN_EMAILS`** = 你的邮箱(逗号分隔)。不设 → 没人能授予蓝V认证 / 进后台。 - [ ] **`TRUST_PROXY`** = 生产默认自动 on;若**不在** nginx/cloudflare 后面才需显式 `false`(否则限流按错 IP)。 - [ ] **`MAX_QUESTION_LEN`** = 默认 2000,按成本/滥用容忍度调。 - [ ] **`MODERATION_MODE` / `MODERATION_URL`**:默认只有内置正则兜底。接专业内容安全服务(`MODERATION_URL`)或 `MODERATION_MODE=llm` 更稳(live 视频对话现在也走审核了)。 ## 🟡 3. 按功能可选(不配=优雅降级,不会崩) | 功能 | 需要的 env | 不配的表现 | |---|---|---| | AI 聊天 / 知识 RAG | `DASHSCOPE_API_KEY` | 聊天 → 502;其余正常 | | Claude 兜底 | `ANTHROPIC_API_KEY` | Qwen 挂了没有兜底 | | 捏脸(万相) | `AVATAR_PROVIDER=dashscope` + 公网 `PUBLIC_URL` | 用上传原图(往往更像本人,OK) | | 声音克隆 / TTS | `DASHSCOPE_API_KEY` | `voice-not-cloned` | | 口播视频(EMO) | `DASHSCOPE_API_KEY` + 公网 `PUBLIC_URL` | 不可用 | | 英文原生发音 | `AZURE_SPEECH_KEY` | 回退克隆音色/浏览器 TTS | | 手机短信登录 | `SMS_PROVIDER=aliyun` + `ALIYUN_SMS_*` | 生产下**直接不可用**(已 fail-closed,不再泄露验证码)※ | | 邮箱找回密码 | `EMAIL_PROVIDER=<非stub>` + 实现 `sendEmail` | 生产下**直接不可用**(已 fail-closed)※ | | 微信扫码登录 | `WECHAT_APP_ID` + `WECHAT_APP_SECRET` | stub 二维码在生产被关,等于登录方式不可用 | | 商店真实收款 | `STORE_PROVIDER=wechat` + `WXPAY_*` 全套 | 生产下 stub 返回 `payment-unavailable`(不再白嫖)| | 媒体持久存储 | `OSS_*` 四要素(region 带 `oss-` 前缀)| 回落本地磁盘,重部署会丢片 | | 分享卡富预览 | `SPA_INDEX_PATH`(+ Nginx 回源)| 回落 meta+跳转壳 | | 公众号转发卡 | `WX_MP_APP_ID/SECRET`(+ JS 安全域名)| 前端休眠 no-op | | 钱包/付费咨询栈 | `FEATURE_MARKETPLACE=true` | 默认关闭(定位「不做平台」)| > ※ 短信/邮箱登录:这是本次安全修复的**有意行为** —— 生产没配真实 provider 就不可用,总比"回传验证码给任何人"强。要启用就配真 provider;不打算用就保证注册/登录还有邮箱密码这条路。 ## ⚪ 4. 可留默认 `PORT` `EDITION=both` `JWT_EXPIRES=7d` `LLM_MODEL` `EMBED_MODEL` `AVATAR_STYLE` `TOKENS_PER_YUAN` 等。 --- ## ✅ 部署后自检(3 条) ```bash # 1) 确认进程真在 production 模式 # 启动日志应含: on :3701 (production) # 2) 生产必须 fail-closed:忘记密码不返回验证码(响应里不应出现 devCode) curl -s -X POST https:///api/auth/password/forgot \ -H 'content-type: application/json' -d '{"email":"someone@x.com"}' # 期望:{"sent":true}(无 devCode)或 502;绝不能出现 devCode 字段 # 3) 微信 mock-scan 后门必须已关(应 404) curl -s -o /dev/null -w "%{http_code}\n" https:///api/auth/wechat/mock-scan/anystate # 期望:404 ``` --- ## ⚠️ 一次性 / 数据层 - 新增集合 `plaza_ratings` + 唯一索引 `{slug,voter}`:首次启动 `connectDb()` **自动建**,无需手动迁移。 - 未改任何既有字段(`isPublic` 等原样),无数据迁移风险。