NodeJS 中的 HTTP 代理服务器

Isaac Tony 2023年1月30日
  1. 在 NodeJS 中使用 HTTP-Proxy 中间件创建一个简单的 HTTP 代理
  2. 在 NodeJS 中使用 required() 方法将我们的依赖项导入到我们的主文件中
  3. 在 NodeJS 中使用代理服务器使用代理服务器重写路径
  4. 在 NodeJS 中使用 curl 工具测试代理服务器和端点
NodeJS 中的 HTTP 代理服务器

代理服务器是位于提供资源的服务器和客户端之间的中间服务器。

代理服务器可以用于最基本的服务器和客户端之间的未修改代理事务。

这些服务器是网关或隧道代理,通常被归类为转发。

此外,用作匿名代理,允许用户匿名浏览。我们还有一个反向代理服务器,一种提供附加服务的代理服务器。

这些服务器的目的是通过提供负载平衡等服务来提高性能、提供安全性并提高可靠性。

反向代理还可以通过保护用户免受 DDoS 攻击、代表主服务器执行 SSL 加密和缓存内容等攻击来为用户提供额外的安全性。

在 NodeJS 中使用 HTTP-Proxy 中间件创建一个简单的 HTTP 代理

他的文章将介绍如何使用 HTTP-proxy 中间件在 NodeJS 中创建一个简单的 HTTP 代理。首先,我们需要创建一个新的 NodeJS 项目并对其进行初始化。

npm init

请记住,你必须在系统上安装 NodeJS 和 npm 才能正常工作。

该命令将允许我们生成一个 package.json 文件,该文件将包含程序中使用的依赖项、作者姓名和许可证。

一旦我们设置好这个基本程序,我们就可以安装 express js 和 http-proxy 中间件。Express js 是一个极简主义的 Web 框架,我们可以在不掩盖 NodeJS 特性的情况下使用它。

Http-proxy 是一个单线 node.js 代理中间件,用于连接、表达和浏览器同步。我们可以使用下面的命令安装它们。

npm install express
npm install npm install --save-dev http-proxy-middleware

运行上面的命令将它们作为依赖项添加到下面的 package.json 文件中。

{
  "name": "proxyy",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "isaac tonyloi",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.2"
  },
  "devDependencies": {
    "http-proxy-middleware": "^2.0.2",
    "install": "^0.13.0",
    "npm": "^8.4.0"
  }
}

在 NodeJS 中使用 required() 方法将我们的依赖项导入到我们的主文件中

我们将首先使用下面所示的 required() 方法将我们的依赖项导入我们的主文件 index.js

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

然后,我们将创建一个简单的快速服务器来侦听端口 8080 和一个代理服务器,它允许我们将请求镜像到目标站点的相应路径。

在此示例中,我们将使用 dummyapi.io 作为目标站点。Dummy API 是一个伪造的数据沙箱 API,它允许我们使用真实和伪造的用户数据。

类似于 jsonplaceholder,但为 REST 数据 API 端点和 GraphQL API 和更多功能提供接口。

在将其发送到目标服务器之前,我们可以使用此代理对我们的路径进行各种更改。例如,我们可以重写、删除基本路径或添加到路径中。

在 NodeJS 中使用代理服务器使用代理服务器重写路径

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();
const PORT = 8080;

const API_SERVICE_URL = "https://dummyapi.io";

app.use('/user_info', createProxyMiddleware({
    target: API_SERVICE_URL,
    changeOrigin: true,
    pathRewrite: {
        [`^/user_info`]: '',
    },
}));

app.listen(PORT, () => {
    console.log(`Proxy server listening at port number:${PORT}`);
});

我们可以通过在终端上执行命令 node index.js 来启动服务器。

输出:

[HPM] Proxy created: /  -> https://dummyapi.io
[HPM] Proxy rewrite rule created: "^/user_info" ~> ""
Proxy server listening at port number:8080

现在,如果我们向端点 localhost:8080/user_info/data/v1/user/60d0fe4f5311236168a109ca 发送请求,代理服务器将将此路径重写为 https://dummyapi.io/data/v1/user/60d0fe4f5311236168a109ca

在 NodeJS 中使用 curl 工具测试代理服务器和端点

我们可以使用 curl 工具来测试这些端点并查看我们的代理服务器的工作情况。请注意,我们还在请求中添加了一个包含 app-id 的标头,如下所示。

curl -H "app-id: 61fcc16fcc2b30f8f01dfdb5" localhost:8080/user_info/data/v1/user/60d0fe4f5311236168a109ca
{"id":"60d0fe4f5311236168a109ca","title":"ms","firstName":"Sara","lastName":"Andersen","picture":"https://randomuser.me/api/portraits/women/58.jpg","gender":"female","email":"sara.andersen@example.com","dateOfBirth":"1996-04-30T19:26:49.610Z","phone":"92694011","location":{"street":"9614, Søndermarksvej","city":"Kongsvinger","state":"Nordjylland","country":"Denmark","timezone":"-9:00"},"registerDate":"2021-06-21T21:02:07.374Z","updatedDate":"2021-06-21T21:02:07.374Z"}

我们已经成功创建了一个 http 代理服务器,它可以重定向和修改对特定服务的请求。

除此之外,我们还可以使用此代理服务器作为身份验证中间件对我们的请求进行授权。

这确保只有授权用户才能访问特定服务。下面是真实软件的简单实现;我们通常有更复杂的授权。

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();
const PORT = 8080;

const service_endpoint = "https://dummyapi.io";

app.use('', (req, res, next) => {
    if (req.headers.authorization) {
        next();
    } else {
        res.sendStatus(403);
    }
 });

app.use('/user_info', createProxyMiddleware({
    target: service_endpoint,
    changeOrigin: true,
    pathRewrite: {
        [`^/user_info`]: '',
    },
}));

app.listen(PORT, () => {
    console.log(`Proxy server listening at port number:${PORT}`);
});

为了测试我们的代理服务器是否授权我们的请求,我们可以向端点发送请求而不包含授权信息。这将返回一个错误,如下所示。

>curl -H "app-id: 61fcc16fcc2b30f8f01dfdb5" localhost:8080/user_info/data/v1/user/60d0fe4f5311236168a109ca

输出:

Forbidden

这意味着我们的授权中间件正在工作,我们需要将凭证传递到标头中才能访问服务。

curl -H "app-id: 61fcc16fcc2b30f8f01dfdb5" -H "Authorization: isaactonyloi" localhost:8080/user_info/data/v1/user/60d0fe4f5311236168a109ca
{"id":"60d0fe4f5311236168a109ca","title":"ms","firstName":"Sara","lastName":"Andersen","picture":"https://randomuser.me/api/portraits/women/58.jpg","gender":"female","email":"sara.andersen@example.com","dateOfBirth":"1996-04-30T19:26:49.610Z","phone":"92694011","location":{"street":"9614, Søndermarksvej","city":"Kongsvinger","state":"Nordjylland","country":"Denmark","timezone":"-9:00"},"registerDate":"2021-06-21T21:02:07.374Z","updatedDate":"2021-06-21T21:02:07.374Z"}
E:\>curl -H "app-id: 61fcc16fcc2b30f8f01dfdb5" localhost:8080/user_info/data/v1/user/60d0fe4f5311236168a109ca
作者: Isaac Tony
Isaac Tony avatar Isaac Tony avatar

Isaac Tony is a professional software developer and technical writer fascinated by Tech and productivity. He helps large technical organizations communicate their message clearly through writing.

LinkedIn