SASL: sram - server语言 - first - message:客户端密码必须是字符串错误类型orm.<


Error: SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string

我在堆栈溢出中寻找了一些解决方案,许多人说这将是一个dotenv问题,但在我的情况下,应用程序在没有对dotenv进行任何修改之前正常工作,我已经尝试过以其他方式导入,错误仍在继续,所以我相信这是一个typeORM错误。

数据库配置

import { DataSource } from "typeorm"
import { User } from "../entities/User"
export const AppDataSource = new DataSource({
type: "postgres",
host: process.env.DATABASE_HOST,
port: 5432,
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
synchronize: true,
logging: true,
entities: [User],
subscribers: [],
migrations: [],
})

实体用户

import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import bcrypt from 'bcryptjs';
@Entity('users')
export class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
username: string;
@Column()
email: string;
@Column()
password: string;
@BeforeInsert()
@BeforeUpdate()
hashPassword() {
this.password = bcrypt.hashSync(this.password, 8);
}
}

应用

import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import dotenv from 'dotenv';
import 'reflect-metadata';
import userRoutes from './src/routes/UserRoutes';
dotenv.config();
const app = express();
app.use(express.json());
app.use(cors());
app.use(bodyParser());
app.use('/user', userRoutes)
export default app;

服务器

import app from './app';
import { AppDataSource } from './src/database/Config';
async function connection() {
const port = process.env.PORT;
try {
await AppDataSource.initialize();
console.log('Database connected! ');
app.listen(port);
console.log(`Listening on port ${port}`)
} catch (error) {
console.log(error);
}
}
connection();

在网上搜索了几天的解决方案后(没有…直到现在),我通过反复试验找到了自己的。

为什么会这样

尽管有些人说dotenv或者你的.env文件是问题,根本原因不是客户端而是服务器端,本地配置疏忽与postgres。

Postgres默认使用本地连接的对等认证方法,同时Node的pg软件包使用sam -sha-256(错误地假设您正在连接到远程服务器)。

这会导致错误,因为Node尝试向服务器发送临时身份验证请求,尽管服务器已经通过peer方法验证了应用程序。

这也是为什么你可以连接到数据库,但仍然得到错误。

Node发送一个scram请求,该请求被消耗,但未被服务器使用,Node看到响应并假设消耗的密码为空,引发上面的错误。

解决方案是什么?

首先,确保设置了postgres帐户密码。如果您的postgres帐户密码为空,也会导致相同的错误。如果您在第一次配置postgres时执行了此操作,则可以跳过此操作。

请切换到您的postgres帐户,访问数据库"postgres"然后将密码更改为非null

sudo su postgres 
psql postgres 
password

密码设置完成后,需要修改postgres的服务端认证方式。

编辑pg_hba.conf文件

/etc/postgresql/15/主/pg_hba.conf

使所有本地/主机连接都使用sam -sha-256认证方法。

默认情况下,

local   all             postgres                                peer

local   all             all                                     peer

将具有peer身份验证方法。

对于其他本地和主机策略默认设置相同的方法。这个peer方法是导致错误的原因。

通过将方法从peer更改为sam -sha-256来修复此问题

# Database administrative login by Unix domain socket
local   all             postgres                                scram-sha-256
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     scram-sha-256
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     scram-sha-256
host    replication     all             127.0.0.1/32            scram-sha-256
host    replication     all             ::1/128                 scram-sha-256`

如果是peer,将其改为sam -sha-256

设置完成后,退出postgres帐户,重新启动postgresql进程,重新加载配置

exit
sudo systemctl restart postgresql

现在,在你的Node应用中,使用一个连接对象或者你的环境变量来连接。

对于.env,确保您的变量名称与这里列出的默认Postgres名称一致。

例如,默认密码环境变量应为PGPASSWORD. 在。env文件中,密码应该是

PGPASSWORD = "MyPassword"
对于连接对象方法,创建一个对象并将其提供给您的新客户端(ObjectHere)
const ConObj = {
user: "postgres", // default process.env.PGUSER || process.env.USER
password: "password", //default process.env.PGPASSWORD
host: "localhost", // default process.env.PGHOST
database: "my_test_database", // default process.env.PGDATABASE || user
port: 5432, // default process.env.PGPORT
application_name: "My Application Name", // The name of the application that created this Client instance
}
const dbConnection = new Client(ConObj)
dbConnection.connect()

一旦所有这些都完成了,错误应该解决。

希望这有助于那里的人,我拔我的头发与这个错误。真高兴它走了……

最新更新