NodeJS Sequelizer和Google Cloud SQL(PostgreSQL):服务器不支持SSL连接

tcomlyy6  于 2023-03-22  发布在  Node.js
关注(0)|答案(1)|浏览(180)

我正在尝试将我的Node.js/Sequelizer应用程序中的sequilizer模型迁移到托管在Google Cloud上的PostgreSQL数据库。GCP要求我使用SSL(或一些复杂的代理)进行连接。
当我运行以下命令时:NODE_ENV=production npx sequelize db:migrate我得到错误:

Sequelize CLI [Node: 19.0.0, CLI: 6.6.0, ORM: 6.29.3]

** config.js **
Loaded configuration file "config/config.js".
Using environment "production".

**ERROR: The server does not support SSL connections**

这是我第一次使用Sequelizer和Google Cloud SQL。我感谢任何帮助。
我可以使用Postico 2上的SSL证书进行连接(连接时确认是TLS 1.3连接),也可以使用BeeKeeper Studio进行连接。在GCP控制台中,我将其设置为仅需要SSL连接(我的项目需要此连接)。
我还使用.sequelizerc设置来覆盖config以调用我的config.js(解决加载证书的其他挑战的唯一方法):

const fs = require('fs');
const path = require('path');

console.log("** config.js **");

module.exports = {
  development: {
    dialect: "sqlite",
    storage: "./database_dev.sqlite3"
  },
  test: {
    username: process.env.CI_DB_USERNAME,
    password: process.env.CI_DB_PASSWORD,
    database: process.env.CI_DB_NAME,
    host: '127.0.0.1',
    port: 5432,
    dialect: 'postgres'
  },
  production: {
    username: process.env.PROD_DB_USERNAME,
    password: process.env.PROD_DB_PASSWORD,
    database: process.env.PROD_DB_NAME,
    host: process.env.PROD_DB_HOSTNAME,
    port: process.env.PROD_DB_PORT,
    dialect: 'postgres',
    ssl: true,
    dialectOptions: {
      ssl: {
        require: true,
        rejectUnauthorized: false,
        ca: fs.readFileSync(path.join(__dirname,'..','ssl','server-ca.pem')),
        cert: fs.readFileSync(path.join(__dirname,'..','ssl','client-cert.pem')),
        key: fs.readFileSync(path.join(__dirname,'..','ssl','client-key.pem'))
      }
    },
    debug: true
  }
};

Dev和Test均已成功迁移。

更新3/21/2023

如下所示,我尝试使用以下连接:

const fs = require('fs');
const { Client, Pool } = require("pg");

const config = {
    user: process.env.PROD_DB_USERNAME,
    password: process.env.PROD_DB_PASSWORD,
    database: process.env.PROD_DB_NAME,
    host: process.env.PROD_DB_HOSTNAME,
    port: process.env.PROD_DB_PORT,
    application_name: "sequelizer-practice",
    // this object will be passed to the TLSSocket constructor
    ssl: {
        rejectUnauthorized: false,
        ca: fs.readFileSync(__dirname + "/ssl/server-ca.pem").toString(),
        key: fs.readFileSync(__dirname + "/ssl/client-key.pem").toString(),
        cert: fs.readFileSync(__dirname + "/ssl/client-cert.pem").toString(),
    },
};

const client = new Client(config);
client.connect((err) => {
    if (err) {
        console.error("error connecting", err.stack);
    } else {
        // console.log("connected");
        client.query("SELECT NOW()", (err, res) => {
            if (err) throw err;
            console.log(res);
            client.end();
        });
    }
});

const pool = new Pool(config);
pool.connect()
    .then((client) => {
        console.log("connected");
        client.release();
    })
    .catch((err) => console.error("error connecting", err.stack))
    .then(() => pool.end());

这连接并从数据库返回了请求的时间戳。但我仍然不知道我在尝试做同样的事情时做错了什么。

fhg3lkii

fhg3lkii1#

我想我发现了这个问题(虽然不是那么简单)。在阅读了Github上Sequelizer Discussion的这篇文章中的评论后,我了解到选项应该直接传递给pg。因为我使用pg,所以我能够缩小差异。
Connect to postgres with ssl mode #15636
结果是Sequelizer为生产配置选择变量的方式在使用.env中的值时出现了问题
当我将用户名、数据库、主机和密码的字符串直接硬编码到config.js中时,它解决了这个问题。
给我的一个教训是,IP地址不会作为环境变量的字符串出现。但请注意,这本身并没有解决这个问题。我必须硬编码用户名和数据库,否则它会试图与我的操作系统用户名连接。

相关问题