返回博客

快速开始指南

安全存储 API 密钥:环境变量、.gitignore、泄露修复

让你的 CheapTokens 密钥远离代码和 git:设置环境变量,把 .env 加入 .gitignore,并了解密钥泄露时该怎么做。

作者:CheapTokens Team发布于 5 分钟阅读

带有环境变量导出和 API 密钥 .gitignore 行的终端
本页内容
  1. 为什么密钥不该写在代码里
  2. 第 1 步:把密钥放进环境变量
  3. 第 2 步:使用 .env 文件但不提交它
  4. 如果密钥泄露了:按顺序做什么
  5. 自我检查

把密钥保存在环境变量中,而不是写在代码里,并通过在 .gitignore 中添加一行,让任何 .env 文件都不进入 git。如果密钥已经出现在某个公开位置,先处理密钥,再收拾残局:在密钥仍留在代码和工具中的情况下清理 git 历史,解决不了任何问题。

这就是全部思路。本指南是实操版本(基础知识见什么是 API 密钥):三条命令、一个可用的请求,以及应对糟糕情况的一份简短计划。

为什么密钥不该写在代码里#

API 密钥是一个能花你钱的密码。任何持有它的人都能用你的余额发送请求,而服务方无法把他们和你区分开。

出错的常见方式很无聊。你把密钥粘贴进脚本,让第一个请求跑通,脚本能用了,你执行 git push,然后仓库就公开了。或者你把配置文件发给了同事。或者你截了一张错误截图,密钥就露在角落里。每次结果都一样。

GitHub 很熟悉这种模式。它的密钥扫描(GitHub 文档,查阅于 2026 年 10 月 29 日)会遍历所有分支的完整 Git 历史,查找硬编码的凭据,也会检查 issue、pull request、讨论、wiki 和 secret gist,一旦发现就发出警报。这意味着在下一个提交中删掉那一行毫无作用:旧提交里仍然有它。

下面是同一个脚本的前后对比。

比较

同一个脚本,密钥已移出代码

密钥写在代码里

python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key="<your-key>",  # pasted here: ends up in git
)

密钥来自环境变量

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

第二个版本可以原样发到 GitHub、聊天窗口或代码评审中。密钥留在你的机器上,在文件之外。

第 1 步:把密钥放进环境变量#

环境变量是一个有名字的值,你的终端会把它交给它启动的每个程序。脚本按名称请求 CHEAPTOKENS_API_KEY,永远看不到它来自哪里。

在 macOS 和 Linux 上:

bash
export CHEAPTOKENS_API_KEY="<your-key>"

在 Windows PowerShell 上:

powershell
setx CHEAPTOKENS_API_KEY "<your-key>"

有两个细节容易让人踩坑。export 只在那个终端窗口中有效,所以要长期保留,就把这一行加到你的 shell 配置文件(~/.zshrc 或 ~/.bashrc)中。而 setx 不会改变你输入它的那个窗口:测试前先打开一个新终端。

现在来一个完整请求。它使用 OpenAI 兼容端点 https://api.cheaptokens.dev/v1,以及带完整 id 的 DeepSeek-V4-Flash(deepseek-ai/DeepSeek-V4-Flash-0731;id 请从 CheapTokens 文档获取,因为不同提供商的名称不同):

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Say hi in five words."}],
)
print(resp.choices[0].message.content)
print(resp.usage)

一句简短问候大约消耗 20 个输入 token 和 20 个输出 token,按当前价格约为 $0.0000023(完整列表见价格页面)。如果你还没发送过第一个请求,使用 CheapTokens 发送你的第一个 API 请求会从零开始带你走一遍。

模型的回答会出现在 choices[0].message.content 中,usage 显示它统计的 token 数。密钥始终不会出现在文件里。

显示 .env 和 .gitignore 命令的终端
让密钥不进入 git 的三条命令

第 2 步:使用 .env 文件但不提交它#

每个新窗口都输入 export 会很烦。.env 文件把值保存在一个地方,就在项目旁边:

text
CHEAPTOKENS_API_KEY=<your-key>

Python 用 python-dotenv 读取它(pip install python-dotenv):

python
from dotenv import load_dotenv
load_dotenv()  # fills os.environ from .env

只有当 git 永远看不到这个文件时,它才是安全的。在第一次提交之前把它加到 .gitignore 中:

bash
echo ".env" >> .gitignore
git check-ignore -v .env

如果一切正常,第二条命令会输出类似 .gitignore:1:.env .env 的内容:git 会告诉你哪条规则在忽略该文件。如果什么都没输出,说明规则没生效。在 Windows 上,用编辑器创建 .gitignore 并写入一行 .env,或者使用 Add-Content .gitignore .env:PowerShell 的 >> 可能写出 UTF-16,而 git 可能会忽略它。

一个陷阱:.gitignore 只影响 git 尚未跟踪的文件。如果 .env 已经被提交过一次,运行 git rm --cached .env 让 git 停止跟踪它,并把里面的密钥视为已泄露(详见下文)。一个好习惯是提交一个 .env.example,里面写变量名和占位符而不是真实值,这样队友就知道该设置什么。

如果密钥泄露了:按顺序做什么#

也许密钥进了公开仓库,也许它出现在截图里,也许你把整个配置粘贴到了论坛帖子中。顺序比任何单一步骤的速度都重要。

GitHub 自己的指导(同一页面,查阅于 2026 年 10 月 29 日)是立即轮换凭据;重写 Git 历史是可选项,而且凭据被撤销后通常没有必要。人们往往反着做:花一个小时清理历史,而密钥仍然有效。别这样。

选择你的情况

你的密钥发生了什么?选择最接近的情况

密钥在一个现已公开的提交中

先从代码中移除密钥,改用环境变量,把 .env 加到 .gitignore 中,并检查余额里有没有不是你发送的请求。清理历史是之后可选的锦上添花,不是紧急部分。

密钥出现在截图或共享文件中

顺序相同:停止在工具中使用那个密钥并改用环境变量,然后尽可能删除帖子或文件。已删除的截图可能早已被复制,所以不要只指望删除。

同一个密钥用在多个工具中

逐一检查所有保存过该密钥的地方:你的 shell 配置文件、.env 文件、编辑器和终端工具,让每一处都指向环境变量,这样只需在一个地方修改。如果某个工具读取变量失败,401/404 故障排查指南会展示错误的样子。

泄露后的三个步骤:把密钥移出代码、更新每个工具、发送测试请求
先把密钥移出代码,再处理每个工具,然后发送测试请求

清理完成后,像第 1 步那样发送一个小测试请求,并检查余额。如果它能正常回答,且余额和请求数看起来正常,清理就完成了;接下来几天留意余额。已经公开过的密钥即使从代码中移除,也应视为已泄露,所以要留意余额和请求数中是否有不是你发送的内容,并且不要在新地方复用那个密钥。关于密钥通常存放的位置,见在哪里接入你自己的 API 密钥。

自我检查#

自己试试试一试:取消设置该变量并运行脚本。你会看到什么?显示答案

Python 会在任何请求离开你的机器之前以 KeyError: 'CHEAPTOKENS_API_KEY' 停止。这是好的失败:脚本在没有密钥时拒绝运行,而不是悄悄使用一个粘贴进去的密钥。如果你看到的是 401,说明变量已设置但密钥错误;对照 401/404 指南检查密钥和地址。