在这篇文章/教程中,我们将使用 NodeJS 创建一个 API 代理服务器,这背后的主要原因是向您展示如何隐藏公共 API 密钥,而不是像我过去那样公开它们。我们所有人都创建了一个应用程序,只是为了了解一个新的库或框架,而实现这一点的最佳方法是使用开放 API(如TMDB)。
这些开放 API 中的大多数都需要在发出请求之前在请求 URL 或标头中添加 API 密钥。无论哪种方式,API 密钥都可能被实际上不拥有此密钥的人窃取和使用。因此,您最终可能会被暂停帐户,或者您的应用程序无法按预期运行。
请记住:API 密钥属于应用程序的服务器端。
话不多说,让我们创建这个 API 代理服务器。为了这篇文章/教程的缘故,我们将使用Wea?ther API。
要求
在开始编码之前,我们需要具备以下条件:
打开 OpenWeatherMapAPI 站,创建一个免费帐户,转到我的 API 密钥并创建一个。
依赖项和脚本
创建应用程序的项目文件夹
壳
cd ~/Documents/tutorialsmkdir api-proxy-server && cd api-proxy-servernpm init -y
安装所需的 NPM 包
npm install -S express cors dotenv axiosnpm install -D nodemon # for faster development
在 package.json 文件中准备脚本
JSON
{ "scripts": { "start": "node index.js", "dev": "nodemon --config nodemon.json" }}
让我们看一下项目的文件夹和文件,以便更清晰地了解结构。
server/├── src│ ├── utils│ │ └── env.js│ └── routes│ └── index.js├── package.json├── nodemon.json├── index.js└── .env3 directories, 6 files
在项目的根目录下创建一个index.js和一个文件。nodemon.json
JSON
// nodemon.json{ "verbose": true, "ignore": ["node_modules/"], "watch": ["./**/*"]}
API_PORT = 1337API_BASE_URL = "https://api.openweathermap.org/data/2.5/weather"API_KEY = "1d084c18063128c282ee3b41e91b6740" # not actually api key; use a valid one
另一个文件是src/utils/env.js负责读取和导出所有环境变量的文件。
JavaScript
require("dotenv").config();module.exports = { port: Number(process.env.API_PORT) || 3000, baseURL: String(process.env.API_BASE_URL) || "", apiKey: String(process.env.API_KEY) || "",};
JavaScript
// importsconst express = require("express");const cors = require("cors");const env = require("./src/utils/env");// Applicationconst app = express();// Middlewaresapp.use(express.json());app.use(express.urlencoded({ extended: true }));app.use(cors());// Routesapp.use("/api", require("./src/routes")); // Every request that starts with /api will be handled by this handler// This route will handle all the requests that are not handled by any other route handlerapp.all("*", (request, response, next) => { return response.status(404).json({ message: "Endpoint not found!" });});// Bootstrap serverapp.listen(env.port, () => { console.log(`Server is up and running at http://localhost:${env.port}`);});
这里的事情很简单;它是一个基本的 ExpressJs 服务器应用程序。在顶部,我们有所需的导入。然后我们有一些需要的中间件,例如JSON中间件,它负责解析带有 JSON 有效负载的传入请求,并且基于body-parser. 接下来,我们在此处管理端点及其处理程序的路由。最后,我们得到了服务器的引导。
让我们看一下/api路由的处理程序。
JavaScript
// server/src/routes/index.jsconst router = require("express").Router();const { default: axios } = require("axios");const env = require("../utils/env");// [GET] Current weather datarouter.get("/", async (request, response, next) => { try { const query = request.query || {}; const params = { appid: env.apiKey, // required field ...query, }; const { data } = await axios.get(env.baseURL, { params }); return response.status(200).json({ message: "Current weather data fetched!", details: { ...data }, }); } catch (error) { const { response: { data }, } = error; const statusCode = Number(data.cod) || 400; return response .status(statusCode) .json({ message: "Bad Request", details: { ...data } }); }});module.exports = router;
请求处理函数将GET我们在调用它时提供的查询字段作为输入。
例如,如果我们没有这个 API 代理服务器,我们的请求看起来像这样
https://api.openweathermap.org/data/2.5/weather?q=Thessaloniki,Greece&appid={API key},但是现在我们已经有了它,我们的请求看起来像这样http://localhost/api?q=Thessaloniki,Greece。不需要添加必填字段appid,因为代理服务器自己将其添加为请求参数。当我们在 OpenWeatherMap API 上发出请求时,我们尽量不显示 API 密钥。
概括
主要概念是将您的公共 API 密钥隐藏在 API 代理服务器后面,以防止用户窃取您的密钥。为了实现这一点,它是创建端点来包装实际开放 API 的端点,在需要此密钥的每个请求中提供代理服务器内的 API 密钥作为环境变量。这种方法的明显缺点是这是一个耗时的过程,在某些情况下甚至不需要。
您可以在此处获取此 API 代理服务器的源代码。
下一步是什么
我正在考虑向这个代理服务器添加一些功能。其中之一是添加缓存功能,以便更快地提供最近请求的数据。另一种是添加速率限制器,以防止用户过度使用 API 并导致服务器崩溃。
如果您想到了另一种隐藏 API 密钥的解决方案,或者您有任何提示或技巧要告诉我,请发表评论。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!