前端如何安全存储 API 密钥 —— 两种实用方案

前端如何安全存储 API 密钥 ------ 两种实用方案

在前端开发中,我们经常需要调用第三方 API(例如 OpenAI、DeepSeek、Google API 等)。

这些 API 通常需要密钥(API Key)来验证身份。
问题是:如果你把密钥直接写在前端代码里,一旦上线,就等于公开给全世界看

本篇文章介绍 两种安全存储前端 API 密钥的方法,让你在项目中都能拿出一个专业答案。


问题背景

  • 前端代码最终会被打包成 JS 文件,所有变量在浏览器里都能被看到
  • 即使你写在 .env 文件里,只要变量被打包进前端,别人仍然可以在浏览器调试工具里看到
  • 所以不能在浏览器端直接使用敏感密钥
  • 解决办法就是:不让密钥出现在客户端

方案 1:环境变量 + 构建时注入(推荐,适用于无需完全隐藏的情况)

原理

  • 密钥不直接写在源码里,而是写在 .env 或云平台的环境变量里
  • 构建时(build)将密钥注入到打包代码中
  • 优点是简单,适合非核心密钥(比如公开 API、统计工具等)

使用示例(Vite 项目)

  1. 本地 .env 文件(不会提交到 GitHub)

    env 复制代码
    VITE_API_KEY=xxxxxx
  2. 代码中引用

    ts 复制代码
    const apiKey = import.meta.env.VITE_API_KEY
    fetch(`https://api.example.com?key=${apiKey}`)
  3. 云端部署时(Vercel / Netlify / Cloudflare Pages)

    • 在平台的 Environment Variables 里添加 VITE_API_KEY
    • 重新部署项目

安全性

  • 风险:构建后,密钥会被写进最终的 JS 文件,别人可以通过浏览器调试查看
  • 适用场景:非敏感信息、公开 API、埋点统计等

方案 2:Serverless 函数代理(最安全,推荐用于敏感密钥)

原理

  • 前端不直接调用第三方 API
  • 前端请求发送到自己的 Serverless API(部署在 Vercel、Netlify 等)
  • Serverless API 在服务端读取环境变量里的密钥,调用第三方 API
  • 返回结果给前端

这样,密钥永远不会出现在浏览器

使用示例(Vercel)

  1. 在 Vercel 项目的 Environment Variables 添加:

    复制代码
    DEEPSEEK_API_KEY=sk-xxxxxx
  2. 创建 /api/deepseek.ts

    ts 复制代码
    export default async function handler(req, res) {
      const response = await fetch('https://api.deepseek.com/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(req.body),
      })
      const data = await response.json()
      res.json(data)
    }
  3. 前端调用:

    ts 复制代码
    const res = await fetch('/api/deepseek', {
      method: 'POST',
      body: JSON.stringify({ prompt: 'Hello AI' }),
    })
    const data = await res.json()

安全性

  • 优点:密钥只存在服务端环境变量,前端看不到
  • 缺点:需要配置 Serverless 函数,稍微复杂
  • 适用场景:所有敏感 API(支付、AI、数据库等)

两种方法对比

特性 方案 1:环境变量 + 构建注入 方案 2:Serverless 代理
密钥是否可见 打包后可见 不可见
配置复杂度
适用场景 非敏感 API 敏感 API
安全性 ★☆☆☆☆ ★★★★★

结论

  • 如果密钥不敏感(比如埋点、测试接口),方案 1 就够了

  • 如果是敏感 API(AI 调用、支付、数据库),必须用方案 2

    "前端直接存储密钥是不安全的,常用两种方法:一种是构建时通过环境变量注入,另一种是通过 Serverless 函数代理 API 请求,确保密钥不暴露给客户端。"