DanLevy.net

保护 Token、API 密钥及机密信息

公有?私有?啥?

Hero image for 保护 Token、API 密钥及机密信息

什么时候需要保护你的 Token?

保护 API Key 和 Token 至关重要

一个疏忽就可能导致你的服务器控制权和数据落入黑客之手。

判断某个特定的 Token 是否必须隐藏不该如此困难——哪怕是基于官方文档!

各种术语的混杂往往让情况变得更糟:tokenskeyscredentialssecretsprivate 以及 public

让我们换个思路,将其简化为 secret(秘密)和 non-secret(非秘密)两类。



🔒 Secret keys

** ‼️ 重要提示:** Secret keys 必须被 Git 忽略,并且在所有浏览器端代码中剔除。《如何安全地处理 Secret》


如何判断你处理的是否为 Secret key


👍 经验法则: 返回 CORS 错误 的服务器通常缺乏浏览器支持。这强烈暗示你必须代理该服务,并将其视为 secret

👍 经验法则: 昂贵的服务(几乎)总是应该被代理或隐藏。

👍 经验法则: 如果你正在执行写入操作(文件上传、插入数据库行),你处理的可能就是 secret keys


用例与特性: Secret keys

核对清单:安全处理 Secret

快速概览

完成以下步骤以从代码中消除 secret:

不要在已部署的服务器上创建 .env 文件。请使用托管服务(如 Heroku、Netlify、AWS EC2)提供的环境变量管理工具:例如控制面板或命令行。

相关文章:在 NodeJS 中安全地使用 dotenv


🌍 Non-secret keys

👍 经验法则: 每当一个密钥必须通过代码或内联方式发送到浏览器时(例如通过 <script src="https://my-api/?apiKey=123-abc-456"> 标签),它绝对是一个 non-secret。一个常见的例子是 Google Maps。


用例与特性: Non-secret keys

✅ 处理 Non-secrets:

硬编码 non-secret(公开)密钥是安全的!

为了方便长期管理,建议在应用中使用共享的 config.js

示例:

config.js
module.exports = {
googleMapsKey: '123-abc'
};
load-map.js
const config = require('./config.js');
const key = config.googleMapsKey;
const src = `//maps.googleapis.com/maps/api/js?key=${key}`;
// ...

注意: 环境变量还有其他用例。本文未涵盖的部分包括:CI/CD/测试、特性开关(feature flags)以及针对特定环境的运行时配置!