Heroku/Postgres "ClientAuthentication" Node 和 node-postgres 出错
Heroku/Postgres "ClientAuthentication" Error with Node and node-postgres
我正处于使用 Postgres 在 Heroku 上开发应用程序的早期阶段。 NodeJS 中问题代码的一个简单版本是:
const {Client} = require('pg');
const client = new Client({connectionString: 'postgres://{username}:{password}@{host}:5432/{dbname}'});
client.connect();
const result = client.query('SELECT now()');
client.end();
connectionString
是 data.heroku.com 的凭据窗格中提供的字符串的副本,已检查并重新检查。我可以:
- 使用来自多个不同本地应用程序(例如 DataGrip)的连接字符串进行连接
- 使用该代码(使用不同的连接字符串)连接到 Docker 图像中的本地版本的 Postgres 运行
我不能:
- 从本地计算机上的 Node 应用程序连接
- 从部署到 Heroku 的 Node 应用程序连接
当代码针对远程数据库失败时,node-postgres 抛出此错误:
{
"length": 168,
"name": "error",
"severity": "FATAL",
"code": "28000",
"file": "auth.c",
"line": "496",
"routine": "ClientAuthentication"
}
使用 Node v14.15.1,node-postgres ("pg") 8.5.1
更新:
可能还值得一提的是,我找不到从 Java 中获取此连接到 fail 的方法……这个错误肯定在 Node <-> node-postgres < -> [底层 postgres 驱动程序] <-> Heroku(即数据库正常,连接正常)...但是在哪里?
在创建 client
对象时添加 ssl: { rejectUnauthorized: false }
解决了我的问题。 (source)
const client = new Client({
connectionString: 'postgres://{username}:{password}@{host}:5432/{dbname}',
ssl: { rejectUnauthorized: false }
});
也许可以尝试添加 extra: { ssl: { rejectUnauthorized: false } }
,如果其他代码没有解决任何问题 (source)
在 Heroku 支持的帮助下,我找到了基于 https://help.heroku.com/MDM23G46/why-am-i-getting-an-error-when-i-upgrade-to-pg-8 的解决方案。 “解决方案 1”对我没有任何改变,但“解决方案 2”(使用 pg-connection-string
)确实有效。
当然值得,我还用基于 NODE_ENV 环境变量的条件包装 SSL,这样代码既可以与 Heroku Postgres 实例一起使用,也可以与本地开发版本一起使用同一个数据库。即:
// centralizing the logic for this so the 'useLocalDb' can be reused
// in multiple functions in the module (in case the logic needs to change
// later, among other reasons)
const useLocalDb = process.env.USE_LOCAL_DB;
// a short version of the working connection code
const {Pool} = require('pg');
const {parse} = require('pg-connection-string')
const config = parse(process.env.DATABASE_URL)
if (!useLocalDb) {
config.ssl = {
rejectUnauthorized: false
}
}
const pool = new Pool(config);
我正处于使用 Postgres 在 Heroku 上开发应用程序的早期阶段。 NodeJS 中问题代码的一个简单版本是:
const {Client} = require('pg');
const client = new Client({connectionString: 'postgres://{username}:{password}@{host}:5432/{dbname}'});
client.connect();
const result = client.query('SELECT now()');
client.end();
connectionString
是 data.heroku.com 的凭据窗格中提供的字符串的副本,已检查并重新检查。我可以:
- 使用来自多个不同本地应用程序(例如 DataGrip)的连接字符串进行连接
- 使用该代码(使用不同的连接字符串)连接到 Docker 图像中的本地版本的 Postgres 运行
我不能:
- 从本地计算机上的 Node 应用程序连接
- 从部署到 Heroku 的 Node 应用程序连接
当代码针对远程数据库失败时,node-postgres 抛出此错误:
{
"length": 168,
"name": "error",
"severity": "FATAL",
"code": "28000",
"file": "auth.c",
"line": "496",
"routine": "ClientAuthentication"
}
使用 Node v14.15.1,node-postgres ("pg") 8.5.1
更新: 可能还值得一提的是,我找不到从 Java 中获取此连接到 fail 的方法……这个错误肯定在 Node <-> node-postgres < -> [底层 postgres 驱动程序] <-> Heroku(即数据库正常,连接正常)...但是在哪里?
在创建 client
对象时添加 ssl: { rejectUnauthorized: false }
解决了我的问题。 (source)
const client = new Client({
connectionString: 'postgres://{username}:{password}@{host}:5432/{dbname}',
ssl: { rejectUnauthorized: false }
});
也许可以尝试添加 extra: { ssl: { rejectUnauthorized: false } }
,如果其他代码没有解决任何问题 (source)
在 Heroku 支持的帮助下,我找到了基于 https://help.heroku.com/MDM23G46/why-am-i-getting-an-error-when-i-upgrade-to-pg-8 的解决方案。 “解决方案 1”对我没有任何改变,但“解决方案 2”(使用 pg-connection-string
)确实有效。
当然值得,我还用基于 NODE_ENV 环境变量的条件包装 SSL,这样代码既可以与 Heroku Postgres 实例一起使用,也可以与本地开发版本一起使用同一个数据库。即:
// centralizing the logic for this so the 'useLocalDb' can be reused
// in multiple functions in the module (in case the logic needs to change
// later, among other reasons)
const useLocalDb = process.env.USE_LOCAL_DB;
// a short version of the working connection code
const {Pool} = require('pg');
const {parse} = require('pg-connection-string')
const config = parse(process.env.DATABASE_URL)
if (!useLocalDb) {
config.ssl = {
rejectUnauthorized: false
}
}
const pool = new Pool(config);