Intermediate 12分钟 3 steps

API Key安全管理最佳实践

学习如何安全地管理和存储API Key,避免密钥泄露导致的安全风险和财产损失。

#安全 #最佳实践 #密钥管理 #前端安全

Prerequisites

  • 了解 API 的基本概念
  • JavaScript/Node.js 基础

Overview

为什么API Key安全很重要?

API Key 是访问 API 服务的凭证,一旦泄露可能导致:

  1. 财产损失:付费API被恶意使用,产生巨额账单
  2. 数据泄露:敏感数据被非法访问
  3. 服务滥用:API配额被耗尽,影响正常业务
  4. 法律风险:被用于非法用途

常见的安全错误

在代码中硬编码 API Key 是最危险的做法。以下是一些应该避免的错误:

  1. 硬编码在前端代码:任何人可以在浏览器中查看源码
  2. 提交到 GitHub:密钥会被永久记录在历史记录中
  3. 写在注释里:开发者疏忽导致泄露
  4. 硬编码在 App 中:反编译可以直接获取密钥

Step-by-Step Guide

1

第一步:使用环境变量

永远不要把 API Key 写在代码里,使用环境变量来存储。

bash
                        # .env 文件(不要提交到版本控制)
API_KEY=your_api_key_here
DATABASE_URL=postgres://...

# .gitignore 添加
.env
.env.local
.env.production
                      
javascript
                        // 读取环境变量
// Node.js
const apiKey = process.env.API_KEY;

// 前端项目使用 .env 文件
// VITE_API_KEY=xxx
const apiKey = import.meta.env.VITE_API_KEY;

// 安全使用示例
async function callApi() {
  const apiKey = process.env.API_KEY;
  if (!apiKey) {
    throw new Error('API Key 未配置');
  }
  
  const response = await fetch('https://api.example.com/data', {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  });
  
  return response.json();
}
                      

Tips

  • 创建 .env.example 文件作为模板,但不包含实际密钥
  • 在 CI/CD 中配置环境变量
  • 定期轮换 API Key
2

第二步:后端代理模式

前端永远不应该直接调用需要 API Key 的服务,应该通过自己的后端服务器转发。

javascript
                        // 后端(Node.js/Express)
const express = require('express');
const axios = require('axios');
const app = express();

// 你的 API Key 只在这里存在
const API_KEY = process.env.API_KEY;

app.get('/api/weather', async (req, res) => {
  try {
    // 后端使用 API Key 调用外部服务
    const response = await axios.get('https://api.weather.com/v1/forecast', {
      params: req.query,
      headers: {
        'X-API-Key': API_KEY
      }
    });
    
    // 返回处理后的数据给前端
    res.json(response.data);
  } catch (error) {
    res.status(500).json({ error: '获取天气失败' });
  }
});

app.listen(3000);

// 前端(只需要调用自己的后端)
// fetch('/api/weather?lat=39.9&lon=116.4')
// 不需要暴露任何 API Key
                      

Tips

  • 后端可以添加缓存、限流、日志等额外功能
  • 前端只调用自己信任的域名
  • 后端可以隐藏具体使用的第三方 API
3

第三步:前端安全措施

即使使用后端代理,前端代码也需要注意安全问题。

javascript
                        // 1. 使用 CSP(内容安全策略)
// 在服务器的 HTTP 头中配置
// Content-Security-Policy: default-src 'self'; script-src 'self'

// 2. 防止 XSS 攻击
function safeRender(data) {
  // 使用 textContent 而不是 innerHTML
  document.getElementById('output').textContent = data;
}

// 3. 使用 HttpOnly Cookie 存储敏感信息
// 服务器设置
// res.cookie('session', sessionId, { httpOnly: true, secure: true });

// 4. 验证请求来源
app.use((req, res, next) => {
  const allowedOrigins = ['https://yourdomain.com'];
  const origin = req.headers.origin;
  
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  
  next();
});

// 5. 添加请求速率限制
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100 // 最多100个请求
});
app.use('/api/', limiter);
                      

Tips

  • 永远不要在 localStorage 中存储敏感信息
  • 使用 HTTPS 确保传输安全
  • 添加 CSRF Token 防止跨站请求伪造

Common Errors & Solutions

API Key 泄露了

立即在 API 提供商后台禁用该密钥,生成新的。检查使用记录,确认是否有异常消费。

前端代码中不小心暴露了 Key

删除 Git 历史记录中的 Key,重新生成新的 Key,更新所有环境配置。

第三方 SDK 在前端暴露了 Key

使用后端代理所有需要认证的请求,确保 Key 只存在于后端。