.env 不是魔法保险箱,它只是配置入口
为什么不把配置直接写进代码
同一份代码可能运行在三个环境:
text
本地 API_URL=http://localhost:3000
测试 API_URL=https://staging-api.example.com
正式 API_URL=https://api.example.com环境变量让代码保持不变,只替换运行配置。
什么属于普通配置
text
运行端口
公开站点地址
日志级别
功能开关什么属于秘密
text
数据库密码
第三方 API Key
JWT 签名密钥
管理员 Service Role Key
私钥秘密必须限制在可信后端和部署平台。
本地 .env
text
DATABASE_URL=真实数据库连接
AI_API_KEY=真实第三方密钥代码读取:
ts
const databaseUrl = process.env.DATABASE_URLPython 可能写:
py
database_url = os.environ.get('DATABASE_URL').env 应加入 .gitignore,但这不代表绝对安全。截图、日志和聊天仍可能泄露。
.env.example
提交到仓库的是模板:
text
DATABASE_URL=
AI_API_KEY=它告诉新开发者需要哪些变量,但不包含真实值。
为什么前端公开变量不能装秘密
Vite 常用 VITE_ 前缀,Next.js 常用 NEXT_PUBLIC_。这类值通常会被打进浏览器 JavaScript。
text
VITE_PUBLIC_API_URL 可以是公开 API 地址
VITE_DATABASE_PASSWORD 绝对不应该存在名字包含 public 不是自动安全,而是提醒它会公开。
线上怎样配置
Cloudflare、Railway、Vercel 等平台都有环境变量设置。通常流程:
- 在平台项目设置中添加变量名和值。
- 选择适用环境,例如 Production。
- 保存后重新构建或重启服务。
- 从日志确认变量是否存在,但不要打印真实值。
判断变量是否加载,不要打印秘密
可以记录:
ts
console.log('DATABASE_URL configured:', Boolean(process.env.DATABASE_URL))不要记录:
ts
console.log(process.env.DATABASE_URL)常见失败
本地改了 .env,应用仍然说缺变量
开发服务器可能只在启动时读取环境变量。停止并重新启动。
本地正常,线上 500
线上平台没有配置同名变量,或只配置到了 Preview 而不是 Production。
变量名看起来一样仍然失败
检查大小写、空格、引号和前缀。AI_API_KEY 与 AI_KEY 是两个名字。
Key 曾经提交到 Git
仅删除当前文件不够,历史 commit 里可能还在。先去服务平台撤销旧 Key、创建新 Key,再更新环境和处理历史。
一份安全检查表
text
.env 在 .gitignore
.env.example 只有字段名
真实秘密只在后端和部署平台
前端公开变量不包含密码
日志不打印真实值
泄露后立即撤销轮换把 API Key 写进 VITE_AI_KEY,再从 React 读取,为什么不安全?
答案:VITE 前缀变量会进入前端构建,用户可以在浏览器代码或请求中提取。第三方秘密 Key 应由后端环境变量读取。