TypeORM 通过代理地址创建连接

问题描述

所以我想做一个包含数据库、后端和移动前端的小项目。我在树莓派上有一个 mariadb 数据库,并且为来自任何地方的连接设置了一切。我使用 TypeORM 创建了我的后端服务器并将其托管在 heroku 上。问题是我的 heroku 服务器有一个动态 IP,我只想拥有少量列入白名单的 IP。所以我将 quotaguard 添加到我的 heroku 应用程序中。问题是设置代理连接(来自 quotaguard documentation)的唯一方法是通过创建 SockConnection 对象的socksjs(再次来自quotaguard 的文档)。我知道如果我使用 mysql.createConnection() 有一个 stream 选项允许我传入该对象,但我没有在 TypeORM 的 createConnection 函数中看到它。我有一个名为 sockConn 的变量,我已经验证了在 quotaguard 仪表板上建立了连接,但我不知道如何将它添加为 TypeORM createConnection 函数的选项。

这是我项目中的 index.ts 文件:

import "reflect-metadata";
import {createConnection,getConnectionManager} from "typeorm";
import express from "express";
import {Request,Response} from "express";
import {Routes} from "./routes";
import { DB_CONNECTION } from "./database";
import { MysqlConnectionOptions } from "typeorm/driver/mysql/MysqlConnectionOptions";
import { config } from 'dotenv';
import { parse } from 'url';
var SocksConnection = require('socksjs');
config().parsed

const setupConnection = () => {
    DB_CONNECTION.username = process.env.DB_USER;
    DB_CONNECTION.password = process.env.DB_PASS;
    DB_CONNECTION.host = process.env.DB_HOST;
    DB_CONNECTION.port = parseInt(process.env.DB_PORT);
    DB_CONNECTION.debug = true;

   // ---- this section from quotaguard documentation ---- //
    var proxy = parse(process.env.QUOTAGUARDSTATIC_URL),auth = proxy.auth,username = auth.split(':')[0],pass = auth.split(':')[1];
    var sock_options = {
        host: proxy.hostname,port: 1080,user: username,pass: pass
    };

    var sockConn = new SocksConnection({host: DB_CONNECTION.host,port: DB_CONNECTION.port},sock_options);
    // ---- this section above from quotaguard documentation ---- //
}

setupConnection();
createConnection(DB_CONNECTION as MysqlConnectionOptions).then(async connection => {

// create express app
const app = express();
app.use(express.json());

// register express routes from defined application routes
Routes.forEach(route => {
    (app as any)[route.method](route.route,(req: Request,res: Response,next: Function) => {
        const result = (new (route.controller as any)())[route.action](req,res,next);
        if (result instanceof Promise) {
            result.then(result => result !== null && result !== undefined ? res.send(result) : undefined);

        } else if (result !== null && result !== undefined) {
            res.json(result);
        }
    });
});

// setup express app here

// start express server
app.listen(3000);

console.log("Express server has started on port 3000. 
Open http://localhost:3000 to see results");

}).catch(error => console.log(error));

可能还有更好的软件包,但由于我从未处理过这种类型的东西,所以我只忽略了文档中的内容。

解决方法

所以我联系了 QuotaGuard,他们给了我一个有效的答案。答案如下:

但是,我们通常建议您使用我们的 QGTunnel 软件进行数据库连接。

QGTunnel 软件是一个包装程序,它从本地主机向您的应用程序提供套接字。然后您连接到该套接字,就好像它是您的数据库一样。以下是 QGTunnel 的一些设置说明。

  1. Download QGTunnel 进入项目的根目录

  2. 登录我们的仪表板并设置隧道

使用 Heroku CLI,您可以使用以下命令登录我们的仪表板: heroku 插件:打开 quotaguardstatic

或者,如果您愿意,可以通过单击应用程序资源选项卡上的 QuotaGuard Static 从 Heroku 仪表板登录。

登录我们的仪表板后,在右上角的菜单中,转到设置。在左侧,点击隧道,然后点击创建隧道。

远程目标:tcp://hostname.for.your.server.com:3306 本地端口:3306 透明:真实 加密:假

此设置假设远程数据库服务器位于 hostname.for.your.server.com 并侦听端口 3306。这通常是默认端口。

本地端口是 QGTunnel 将侦听的端口号。在本例中我们将其设置为 3306,但如果您有另一个进程使用 3306,则可能需要更改它(即:3307)。

透明模式允许 QGTunnel 将 hostname.for.your.server.com 的 DNS 覆盖为 127.0.0.1,从而将流量重定向到 QGTunnel 软件。这意味着您可以连接到 hostname.for.your.server.com 或 127.0.0.1 以通过隧道进行连接。

加密模式可用于对数据进行端到端加密,但如果您的协议已经加密,则无需花时间进行设置。

  1. 更改您的代码以通过隧道进行连接 使用透明模式和匹配的本地和远程端口,您不需要更改代码。您也可以连接到 127.0.0.1:3306。

如果没有透明模式,您将需要连接到 127.0.0.1:3306。

  1. 更改您的启动代码。 更改启动应用程序的代码。在 heroku 中,这是通过 Procfile 完成的。基本上你只需要在你的启动代码前面加上“bin/qgtunnel”。

所以对于之前的 Procfile: web: your-application 你的论点 你现在想要: web: bin/qgtunnel your-application 你的论点

如果您没有 Procfile,则 heroku 将根据您使用的框架或语言使用默认设置代替 Procfile。您通常可以在 Heroku 仪表板中应用程序的概览选项卡上找到此信息。它通常位于“Dyno 信息”标题下。

  1. 提交并推送您的代码。 确保文件 bin/qgtunnel 已添加到您的存储库中。

如果您使用透明模式,请确保将 vendor/nss_wrapper/libnss_wrapper.so 也添加到您的存储库中。

  1. 如果您遇到问题,请启用环境变量 QGTUNNEL_DEBUG=true,然后在查看日志的同时重新启动您的应用程序。将日志中的任何信息发送给我。请遮盖所有敏感信息,包括您的 QuotaGuard 连接网址。

非常重要 7. 一切正常后,我建议您从我们的仪表板下载 QGTunnel 配置作为 .qgtunnel 文件并将其放在项目的根目录中。这可以防止您的项目在启动期间不依赖我们的网站。

这对我有用,而且我能够连接到我的数据库。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...