React里把API Key写在组件里提交请求,这样会不会泄露?

翌萱 Dev 阅读 27

我在写一个天气查询组件时,直接把OpenWeatherMap的API Key写在React组件的请求里了。但同事说这样部署后会被别人直接看到,应该怎么办?我试过用.env文件存变量,但开发环境老报401错误…


function Weather() {
  const API_KEY = 'my-secret-key-12345'; // 这样写有问题吗?
  useEffect(() => {
    fetch(`https://api.openweathermap.org/data/2.5/weather?q=London&appid=${API_KEY}`)
      .then(res => res.json())
      .then(data => console.log(data));
  }, []);
  return 
Weather data here
; }

后来改用process.env.REACT_APP_API_KEY后,开发服务器能跑通,但构建生产版本时又提示无效密钥。难道环境变量只能用在特定环境?有没有更安全的存储方式?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
a'ゞ爱玲
问题应该出在环境变量的配置方式上。前端暴露API Key是通病,但可以通过正确使用环境变量来规避风险。

你用 .env 文件是对的,但需要注意几点:

1. 确保你的环境变量名以 REACT_APP_ 开头,比如 REACT_APP_API_KEY,否则在构建时不会被注入。
2. .env 文件必须放在项目根目录下,**不是 src 目录**。
3. 开发环境和生产环境读取的是不同的 .env 文件,比如 .env.development.env.production,确保你为不同环境配置了正确的值。

你的代码大致没问题,调整后可以这样写:

function Weather() {
useEffect(() => {
const API_KEY = process.env.REACT_APP_API_KEY;
fetch(https://api.openweathermap.org/data/2.5/weather?q=London&appid=${API_KEY})
.then(res => res.json())
.then(data => console.log(data));
}, []);

return <div>Weather data here</div>;
}


如果你在生产构建时报错,很可能是 .env.production 没有配置或者被忽略了。你可以临时在代码里打印一下 process.env.REACT_APP_API_KEY,确认是否真的读到了。

真正安全的做法是:**前端不该直接调用带API Key的第三方接口**,中间应该加一层后端代理。这样Key可以藏在服务端,前端只调自己的接口。比如用Node.js做个简单中转服务:

// Node.js后端示例
app.get('/weather', async (req, res) => {
const response = await fetch(https://api.openweathermap.org/data/2.5/weather?q=London&appid=${process.env.OPEN_WEATHER_API_KEY});
const data = await response.json();
res.json(data);
});


前端只调 /weather 接口即可,这样API Key就不会暴露出去。
点赞 10
2026-02-04 15:07
Good“广云
直接把API Key写在前端代码里确实会有泄露风险,因为打包后的代码容易被反编译。用.env文件是个正确方向,但你需要改一下后端逻辑才能彻底解决。

简单说,前端环境变量只能用于开发调试,生产环境需要通过后端代理请求来保护密钥。下面给个完整方案:

1. 后端写个简单的代理接口,比如用Express:
const express = require('express');
const axios = require('axios');
const app = express();

const API_KEY = 'your-secret-key';

app.get('/weather', async (req, res) => {
try {
const response = await axios.get(
https://api.openweathermap.org/data/2.5/weather?q=${req.query.q}&appid=${API_KEY}
);
res.json(response.data);
} catch (error) {
res.status(500).send(error.message);
}
});

app.listen(3001, () => console.log('Proxy server running on port 3001'));


2. 前端改成调用你的代理接口:
useEffect(() => {
fetch('http://localhost:3001/weather?q=London')
.then(res => res.json())
.then(data => console.log(data));
}, []);


这样API Key就安全地保存在后端了。至于你之前401错误,可能是环境变量没正确加载或者生产构建时路径不对。不过既然都做代理了,这些麻烦就不用管了。
点赞 5
2026-02-01 09:24