使用 API 代理服务器隐藏您的 API 密钥

在这篇文章/教程中,我们将使用 NodeJS 创建一个 API 代理服务器,这背后的主要原因是向您展示如何隐藏公共 API 密钥,而不是像我过去那样公开它们。我们所有人都创建了一个应用程序,只是为了了解一个新的库或框架,而实现这一点的最佳方法是使用开放 API(如TMDB)。

这些开放 API 中的大多数都需要在发出请求之前在请求 URL 或标头中添加 API 密钥。无论哪种方式,API 密钥都可能被实际上不拥有此密钥的人窃取和使用。因此,您最终可能会被暂停帐户,或者您的应用程序无法按预期运行。

请记住:API 密钥属于应用程序的服务器端。

话不多说,让我们创建这个 API 代理服务器。为了这篇文章/教程的缘故,我们将使用Wea?ther API。

要求

在开始编码之前,我们需要具备以下条件:

  • API 密钥
    打开 OpenWeatherMapAPI 站,创建一个免费帐户,转到
    我的 API 密钥并创建一个。
  • JavaScript和NodeJS的基础知识
  • java
  • 依赖项和脚本

    创建应用程序的项目文件夹

    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进行处理,非常感谢!

    上一篇 2022年7月3日
    下一篇 2022年7月3日

    相关推荐