AI 开发者必看:把 API Key 留在代码中,5 分钟被爬,一夜欠费上万
别让你的 API 密钥在代码里“裸奔”,这是每个开发者都该有的安全意识。
凌晨三点,你被叮当作响的短信提示音吵醒。监控告警显示,你的云服务账户在一小时内产生了数千美元的异常消费。你慌忙登录控制台,发现一个陌生的 IP 正在疯狂调用你的大模型 API。翻看最近的代码提交记录,一切都指向了那个被你随手写在 config.js 里的 sk-xxx 密钥——因为你把它连同代码一起 push 到了 GitHub 公共仓库,被爬虫在几秒内抓取并利用了。
这并非危言耸听,而是每天都在发生的真实安全事件。把 API Key 写进代码,无异于把家门钥匙藏在大门的锁孔上^_^。
一、为什么“把 API Key 写进代码”是危险的?
-
版本控制系统无法隐藏秘密:Git 的设计初衷是永久保留历史。即使你发现泄露后紧急删除并强制推送,只要密钥曾经存在于任何一次 commit 中,攻击者就能通过
git reflog或直接克隆历史记录将其找回。 -
内部威胁与意外暴露:代码会在多个环节流动:本地开发、同事审查、CI/CD 构建、容器镜像、日志输出。
-
维护与轮换极其痛苦:当密钥过期或需要更换时,硬编码方式意味着你必须修改所有相关源文件,然后重新构建、测试、部署。更可怕的是,如果你在不同文件里重复定义了这个密钥(例如同时出现在
app.js和worker.js),漏掉一个就是生产事故。 -
合规性风险:GDPR、PCI-DSS、等保2.0等法规明确要求,敏感凭证不得以明文形式存储在代码仓库中。一旦审计发现,轻则整改,重则面临巨额罚款。
二、环境变量是什么?
环境变量可以理解成程序启动前,外部提前塞给它的一套“随身便签”。程序运行时完全不管便签是谁写的、从哪来的,只要需要密钥或地址,直接翻翻口袋看一眼就行。
用环境变量来存 API Key,说白了就是三大好处:
- 一套代码,走遍天下:代码只写一次,到了不同的环境(比如测试环境、线上环境),只需要换掉口袋里的“便签内容”就行,代码本身一个字都不用改。
- 钥匙和锁彻底分开:敏感的 API Key 只写在便签(环境变量)上,而这个便签绝不放进代码仓库。哪怕你的代码被公开到 GitHub 上,别人翻遍代码也找不到钥匙在哪。
- 谁该看什么,分得清清楚楚:普通开发人员口袋里只有测试环境的钥匙,线上生产环境的最高权限钥匙只攥在运维负责人手里。权限天然隔离,谁也偷不到自己不该看的东西。
三、如何在代码中正确使用环境变量
如果你正在用 OpenAI、Claude、智谱、文心、通义千问、DeepSeek 等大模型的 API 开发应用,那这一章就是给你量身定制的。因为你的 API Key 直接跟计费绑定——别人偷了你的 Key,就等于拿着你的银行卡去随便刷。
3.1 坏习惯:教程怎么教,你就怎么写
很多 AI 入门教程为了省事,会这样写:
# ❌ 千万别学!这是教程写法,不是生产写法
from openai import OpenAI
client = OpenAI(
api_key="sk-proj-abc123def456..." # 明文写在代码里
)
或者更过分,直接写在 config.json 里再 import:
{
"openai_key": "sk-proj-abc123def456..."
}
后果是什么? 你把代码 push 到 GitHub 的那一刻,就会有爬虫在几分钟内扫到这个 Key,然后用你的额度去疯狂调用模型。半夜你睡着的时候,账单已经多出了几千刀。
3.2 好习惯:从环境变量读取 Key
正确的做法只有一句话:代码里只写读取逻辑,不写真实 Key。
第一步:在项目根目录创建 .env 文件(记住:这个文件永远不提交到 Git)
# .env
OPENAI_API_KEY=sk-proj-你的真实密钥
第二步:把 .env 加入 .gitignore
# .gitignore
.env
.env.local
第三步:在代码里从环境变量读取
# ✅ 正确写法:从环境变量读取
import os
from openai import OpenAI
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise ValueError("请设置环境变量 OPENAI_API_KEY")
client = OpenAI(api_key=api_key)
或者更简洁一点,因为 OpenAI 的 SDK 默认会自动读 OPENAI_API_KEY 这个环境变量:
# ✅ 更简洁:SDK 自动读取环境变量
from openai import OpenAI
client = OpenAI() # 默认从环境变量 OPENAI_API_KEY 读取
第四步:创建一个 .env.example 模板文件(这个可以提交到仓库,供团队成员参考)
# .env.example —— 只写变量名,不写真实值
OPENAI_API_KEY=your_api_key_here
OPENAI_BASE_URL=https://api.openai.com/v1
MODEL_NAME=gpt-4o
3.3 主流 AI SDK 的环境变量写法速查
不管你用哪家的大模型,套路完全一样:
| AI 服务 | 环境变量名 | 代码读取方式 |
|---|---|---|
| OpenAI | OPENAI_API_KEY |
os.getenv("OPENAI_API_KEY") |
| Anthropic Claude | ANTHROPIC_API_KEY |
os.getenv("ANTHROPIC_API_KEY") |
| 智谱 (Zhipu) | ZHIPU_API_KEY |
os.getenv("ZHIPU_API_KEY") |
| 百度文心 | BAIDU_API_KEY + BAIDU_SECRET_KEY |
分别读取两个环境变量 |
| 阿里通义 | DASHSCOPE_API_KEY |
os.getenv("DASHSCOPE_API_KEY") |
| DeepSeek | DEEPSEEK_API_KEY |
os.getenv("DEEPSEEK_API_KEY") |
💡 通用公式:
你的 AI 服务商名 + _ + API_KEY,全部大写,下划线分隔。业界标准,照做就行。
3.4 如果你用的是 AI 编程助手(Cursor / Copilot 等)
这些工具本身会帮你管理 Key,但你写的应用代码里同样不能硬编码。尤其是你在 AI 助手的辅助下生成代码时,一定要主动告诉它:
“请从环境变量读取 API Key,不要硬编码。”
一个好的 AI 编程助手会帮你生成类似这样的代码:
// AI 生成的正确代码(Node.js 示例)
const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) throw new Error('OPENAI_API_KEY is not set');
而不是把 Key 直接写在源码里。你才是代码的最终负责人,AI 写的每一行你都要过脑子。
3.5 一个完整的 AI 调用示例(Node.js + OpenAI)
// app.js —— 完整的 AI 调用示例
import 'dotenv/config';
import OpenAI from 'openai';
// 从环境变量读取
const apiKey = process.env.OPENAI_API_KEY;
const baseURL = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
if (!apiKey) {
console.error('❌ 请设置环境变量 OPENAI_API_KEY');
process.exit(1);
}
const client = new OpenAI({ apiKey, baseURL });
async function askAI(prompt) {
const response = await client.chat.completions.create({
model: process.env.MODEL_NAME || 'gpt-3.5-turbo',
messages: [{ role: 'user', content: prompt }],
});
return response.choices[0].message.content;
}
// 调用
askAI('Hello AI').then(console.log).catch(console.error);
3.6 给 AI 开发者的额外忠告
- 永远不要把
sk-开头的 Key 写在任何代码文件里,连注释里都不行。 - 永远不要在日志里打印
api_key的值,调试完记得删掉console.log(api_key)。 - 如果你用 Vercel / Netlify / 阿里云函数计算 部署 AI 应用,去平台的控制台里设置环境变量,不要在代码里写。
- 定期轮换 Key:各大 AI 平台都支持生成多个 API Key,定期更换旧 Key 是良好习惯。
- 如果怀疑 Key 泄露,立即去官网后台删除旧 Key,生成新 Key,不要犹豫。
四、动手演示:重构一段“坏代码”
重构前(危险):
// config.js
export const config = {
apiKey: 'sk-abc123def456ghi789', // 硬编码!
dbPassword: 'admin123',
};
重构后(安全):
// .env.example (提交到仓库)
API_KEY=your_api_key_here
DB_PASSWORD=your_db_password_here
// .env (本地开发,已忽略)
API_KEY=sk-real-secret
DB_PASSWORD=real-password
// config.js (仅读取环境变量)
export const config = {
apiKey: process.env.API_KEY,
dbPassword: process.env.DB_PASSWORD,
};
// 启动验证
if (!config.apiKey || !config.dbPassword) {
throw new Error('Missing required environment variables. Check your .env file.');
}
对比:代码从“充满秘密”变成“干干净净”,安全等级瞬间拉满。
五、总结
环境变量不是什么高深的技术,它简单、成熟、有效,是软件工程安全领域的基石之一。将 API Key 从代码中请出去,不仅是对公司资产负责,更是专业开发者的基本职业素养。
从你正在写的下一个项目开始,甚至从今天提交的这段代码开始,把硬编码的密钥替换成 process.env.KEY。别忘了,随手创建的 .env.example 并提交,能让团队协作更加顺畅。
安全无小事,编码需谨慎。如果这篇文章帮助你避免了一次潜在的泄露事故,那么它便有了意义。

浙公网安备 33010602011771号