简介
当你上线一个 AI 生成的 Web 应用时,代码只是战斗的一半。另一半是代码所连接的一切——推理服务的 API 密钥、数据库连接字符串、第三方服务凭证以及功能开关。在生产环境中处理不当这些内容,是真实故障和真实安全事故最常见的诱因。
本课程讲解一套实用的工作流程,用于在三个环境中保障密钥安全:本地开发、预发布和生产环境。你将学会一套通用的心智模型,无论你部署在 Vercel、Railway、Render、Fly.io 还是裸 VPS 上都能适用。
三个环境
你构建的每个应用至少运行在三个地方,而每个地方对密钥有不同的规则。
本地开发发生在你的笔记本电脑上。你需要快速迭代,因此密钥存放在被 git 忽略的 `.env` 文件中。你可以使用类似 `dotenv` 的库来加载它们。该文件永远不会被提交,也永远不会离开你的机器。
预发布环境是使用伪造数据复刻的生产副本。它存在的目的是在用户看到之前捕获 Bug。密钥由托管服务(Railway Variables、Vercel Environment Variables 等)注入,并且仅在该环境范围内生效。
生产环境是真实用户访问的地方。密钥来自同一个托管服务,但存放在更严格的命名空间中,通常带有独立的访问控制。预发布环境的密钥泄露是件麻烦事;生产环境的密钥泄露则是一场计费灾难。
在代码中加载环境变量
下面的模式几乎适用于所有 Node.js 或 Python 后端。核心思路是:在启动时读取一次,如果必需的密钥缺失就立即报错。
注意这里的启动检查。与其在凌晨 3 点悄悄地把 `undefined` 发送给数据库客户端,不如让程序在启动时直接崩溃。`dotenv` 只会在文件存在时才读取它,这意味着同一份代码无需任何修改就能在生产环境运行——生产环境由主机直接注入环境变量。
在 Python 中,可以使用 `pydantic-settings` 来实现同样的效果:
如果任何必需字段缺失,Pydantic 会抛出一个清晰的验证错误,从而实现同样的 fail-fast(快速失败)行为。
数据库连接模式
对于托管服务(如 Neon、Supabase 或 Railway)上的 Postgres 数据库,连接字符串就是你的密钥,务必像对待密码一样保管好它。
这里有两点很重要。第一,连接池可以避免应用在每次请求时都新建一个 TCP 连接。第二,生产环境必须使用 SSL。许多托管数据库会拒绝未加密的连接,但显式声明 SSL 可以在默认配置发生变化时保护你的应用。
对于无服务器平台(Vercel Functions、Cloudflare Workers),请使用一个位于函数外部的连接池——Neon 内置了连接池,Supabase 则提供了 `pgbouncer` 的 transaction 模式。上面创建的 pool 对象存放在进程内存中,在无服务器环境下意味着每次冷启动都会创建一个全新的连接池,这不仅速度慢,在流量激增时还可能耗尽数据库连接。
管理 AI 服务的 API 密钥
AI API(OpenAI、Anthropic、Google 等)按 token 计费。一旦密钥泄露,可能在几小时内就刷爆你的信用卡。遵循以下三条规则可以保障安全。
首先,在服务商后台设置硬性消费额度。每个主流服务商都提供这一功能。其次,为每个环境创建独立的密钥——`myapp-dev`、`myapp-staging`、`myapp-prod`——这样你可以在不影响其他环境的情况下单独吊销某一个。第三,永远不要在日志中输出密钥,也永远不要把它包含在发送给日志服务的错误信息中。
错误处理器会捕获响应体用于调试,这是可以接受的,因为它不包含密钥——只有上游提供商的错误信息。如果你需要记录请求头用于调试,请先对 `Authorization` 字段进行脱敏处理。
常见错误及如何避免
最常见的错误是提交了 `.env` 文件,哪怕只有一次。Git 历史是永久的,机器人会在推送后几分钟内扫描 GitHub寻找暴露的密钥。从第一天起就将 `.env` 加入 `.gitignore`,并在 CI 中使用 `git-secrets` 或 `gitleaks` 等工具阻止意外提交。
第二个错误是开发和测试共用同一个数据库。看起来很方便,直到本地脚本中一个 `DROP TABLE` 把生产数据清空。务必为每个环境使用独立的数据库,理想情况下还应使用独立的提供商项目。
第三个错误是毫无规划地轮换密钥。当你轮换数据库密码时,应用的每个运行实例在重启之前都将无法重新连接。如果平台支持,使用包含密码的连接字符串,并设计应用在启动时进行重试。在 Vercel 等平台上,轮换密钥后重新部署即可自动完成此操作。
总结
将每一个密钥都视为明天就会泄露——因为终有一天它会的。本地使用 `.env` 文件配合 `dotenv` 或 `pydantic-settings`,让托管平台在预发布和生产环境中注入变量,在启动时验证必需的密钥,在生产环境中使用 `ssl: true` 的数据库连接池,并为每个 AI API 密钥设置消费限额,每个环境使用独立的密钥。整个配置只需一个下午即可完成,却能帮助你规避最常见的生产事故类别。
课程检查点
巩固所学知识,获取作业反馈。