MySQL 8.0客户端不支持服务器请求的认证协议;考虑升级MySQL客户端

由于某种原因,我无法建立到服务器的简单连接。我安装了最新的MySQL Community 8.0数据库以及默认设置的Node.JS。

这是我的node。js代码

    var mysql = require('mysql');


var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});


con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});

以下是在命令提示符中发现的错误:

C:\Users\mysql-test>node app.js
C:\Users\mysql-test\node_modules\mysql\lib\protocol\Parse
r.js:80
throw err; // Rethrow non-MySQL errors
^


Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
at Handshake.Sequence._packetToError (C:\Users\mysql-
test\node_modules\mysql\lib\protocol\sequences\Sequence.js:52:14)
at Handshake.ErrorPacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\sequences\Handshake.js:130:18)
at Protocol._parsePacket (C:\Users\mysql-test\node_mo
dules\mysql\lib\protocol\Protocol.js:279:23)
at Parser.write (C:\Users\mysql-test\node_modules\mys
ql\lib\protocol\Parser.js:76:12)
at Protocol.write (C:\Users\mysql-test\node_modules\m
ysql\lib\protocol\Protocol.js:39:16)
at Socket.<anonymous> (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:103:28)
at Socket.emit (events.js:159:13)
at addChunk (_stream_readable.js:265:12)
at readableAddChunk (_stream_readable.js:252:11)
at Socket.Readable.push (_stream_readable.js:209:10)
--------------------
at Protocol._enqueue (C:\Users\mysql-test\node_module
s\mysql\lib\protocol\Protocol.js:145:48)
at Protocol.handshake (C:\Users\mysql-test\node_modul
es\mysql\lib\protocol\Protocol.js:52:23)
at Connection.connect (C:\Users\mysql-test\node_modul
es\mysql\lib\Connection.js:130:18)
at Object.<anonymous> (C:\Users\mysql-test\server.js:
11:5)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
at Function.Module.runMain (module.js:701:10)
我读过一些东西,比如: https://dev.mysql.com/doc/refman/5.5/en/old-client.html # EYZ0 < / p >

但是我仍然不确定如何解决我的问题。任何帮助都将不胜感激

819022 次浏览

在MYSQL Workbench中执行以下查询

# EYZ0

其中root作为您的用户 localhost作为你的URL 和password作为你的密码

然后运行这个查询刷新特权:

# EYZ0

在执行此操作后尝试使用node进行连接。

如果那不工作,尝试它没有@'localhost'部分。

只要运行MySQL服务器安装程序和重新配置我的SQL服务器…这对我很管用。

我有同样的问题与MySQL和我解决使用XAMPP连接MySQL和停止服务在窗口MySQL(控制面板-管理工具-服务),并在文件夹db.js(负责数据库),我使密码为空(在这里你可以看到:)

const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: ''
});

您可以在这里找到原始文档:https://dev.mysql.com/doc/dev/connector-nodejs/8.0/

'use strict';


const mysqlx = require('@mysql/xdevapi');


const options = {
host: 'localhost',
port: 33060,
password: '******',
user: 'root',
schema: 'yourconference'
};


mysqlx.getSession(options)
.then(session => {
console.log(session.inspect());
session.close();
}).catch(err => {
console.error(err.stack);
process.exit(1);
});

在Mysql最新的docker容器

ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';

使用旧的mysql_native_password可以工作:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourRootPassword';
-- or
CREATE USER 'foo'@'%' IDENTIFIED WITH mysql_native_password BY 'bar';
-- then
FLUSH PRIVILEGES;

这是因为caching_sha2_password是在MySQL 8.0中引入的,但是Node.js版本还没有实现。您可以查看这个拉请求这个问题了解更多信息。可能很快就会修复!

对于已安装在Windows 10上的mysql 8.0,

  1. < p >启动安装程序,

  2. < p >单击“Reconfigure"在QuickAction下(MySQL Server左边),然后

  3. 点击next通过接下来的2个屏幕,直到到达

  4. at "Authentication Method",选择"Use Legacy Authentication Method(保留MySQL 5.)x compatibility"

  5. 继续单击,直到安装完成

虽然接受的答案是正确的,但我更喜欢创建一个新用户,然后使用该用户访问数据库。

create user nodeuser@localhost identified by 'nodeuser@1234';
grant all privileges on node.* to nodeuser@localhost;
ALTER USER 'nodeuser'@localhost IDENTIFIED WITH mysql_native_password BY 'nodeuser@1234';

我在服务器上有MYSQL和另一个服务器上的nodejs应用程序

在MYSQL Workbench中执行以下查询

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password

MySQL 8的完整步骤

连接MySQL

$ mysql -u root -p
Enter password: (enter your root password)

重置密码

(将your_new_password替换为您想要使用的密码)

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
mysql> FLUSH PRIVILEGES;
mysql> quit

然后尝试使用node连接

总结

  1. 如果你只是想摆脱错误,以项目的安全为代价(例如,这只是一个个人项目或开发环境),使用@Pras的回答ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password',然后是flush privileges
  2. 如果你想要修复它,不知道为什么,只需安装和使用mysql2(而不是mysql),并使用它- npm i mysql2mysql = require('mysql2');
  3. 如果你是一个好奇的开发人员,总是渴望学习,请继续阅读……:)

这是怎么呢

让我们先弄清楚发生了什么。

MySQL 8支持可插入的身份验证方法。默认情况下,使用了其中一个名为caching_sha2_password的,而不是我们以前的mysql_native_password ()。很明显,使用加密算法与几次握手比简单的密码传递更安全,24年已经存在!

现在,问题是Node中的mysqljs(你用npm i mysql安装的包,并在你的Node代码中使用它)还不支持MySQL 8的这种新的默认身份验证方法。问题在这里:https://github.com/mysqljs/mysql/issues/1507,截至2019年7月,3年后仍然开放。

现在有一个mysqljs中的新PR来解决这个问题!

显然是计划在mysqljs的第3版中发布

显然它仍然不在然而(至少到2020年4月)中,但node-mysql2支持身份验证切换请求声称。如果node-mysql2在这个问题上工作得很好,请在下面评论——我稍后会自己测试。

似乎这个问题仍然存在,就在3天前,有人发明了一个叉子已经出现了——但在mysql.js包中还没有正式发布。此外,根据下面的评论,mysql2包工作正常,支持Authentication-switch工作正常。


你目前的选择

选项1:[不建议]降级“mysql”;使用mysql_native_password进行身份验证;

这是每个人在这里的建议(例如上面的答案)。你只需进入mysql并运行一个查询,说root可以使用旧的mysql_native_password方法进行身份验证:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password ...

好消息是,生活将变得简单,你仍然可以使用好的老工具,如Sequel Pro没有任何问题。但问题是,你没有利用更安全(也更酷,请阅读下文)的东西。

选项2)[Meh…取代“;Node"MySQL connect X DevAPI包

MySQL X DevAPI for NodeNode的Mysqljs包的替代品,由http://dev.mysql.com官方人员提供。

它支持caching_sha2_password身份验证。(只要确保你使用端口33060协议通信。)

糟糕的是,您留下了我们的旧的mysql包,每个人都非常习惯和依赖它。

好消息是,你的应用现在更安全了,你可以利用我们的老朋友没有提供的大量新东西!只要看看X DevAPI教程,你就会发现它有大量的性感新功能,可以派上用场。你只需要为学习曲线付出代价,这是任何技术升级都必然会出现的。:)

PS:不幸的是,这个XDevAPI包还没有类型定义(TypeScript可以理解),所以如果你在打印稿上,你会有问题。我试着生成。d。ts使用dts-gendtsmake,但没有成功。记住这一点。

选项3)[推荐]替换“mysql.js”;与“mysql2.js"包

如上所述,mysql包(NPM包链接)是还有这个问题(截至2021年4月)。但是mysql2包(NPM包链接)不是。因此,下面的答案可能只需要一行代码!

npm un mysql && npm i mysql2

请注意,mysql2mysql的衍生作品,但它的受欢迎程度(2020年4月mysql2每周62万次下载)已经接近原始包(2021年4月mysql每周72万次下载),所以转换似乎是合理的!

干杯!

如果您遇到了这个问题,但仍然希望使用MySQL的版本8,您可以使用。当使用Docker创建数据库时,您可以通过指示MySQL服务器实现遗留的身份验证插件来完成此任务。

因此,您的compose文件将如下所示:

# Use root/example as user/password credentials


version: '3.1'


services:


db:
image: mysql:8.0.15
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'pass'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'pass'
ports:
- 3318:3306
# Change this to your local path
volumes:
- ~/Database/ORM_Test:/var/lib/mysql

检查MySQL用户的权限和用户名/密码。

对于捕捉错误,使用覆盖的_delegateError方法总是有用的。在你的情况下,这必须看起来像:

var mysql = require('mysql');


var con = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
insecureAuth : true
});


var _delegateError = con._protocol._delegateError;


con._protocol._delegateError = function(err, sequence) {
if (err.fatal)
console.trace('MySQL fatal error: ' + err.message);


return _delegateError.call(this, err, sequence);
};


con.connect(function(err) {
if (err) throw err;


console.log("Connected!");
});

这个构造将帮助您跟踪致命错误。

如果ALTER USER…命令行不适合你,如果你用的是Windows 10,那就试试下面的步骤:

1)在windows搜索栏中输入MySQL

2)打开MySQL Windows安装程序- Community

3)查找“MySQL服务器”,然后单击“重新配置” # EYZ0 < / p >

4)点击“下一步”,直到进入“认证方法”阶段

5)在“认证方法”阶段,检查第二个选项“使用传统认证方法” # EYZ0 < / p >

6)然后按照Windows安装程序给出的步骤直到结束

7)完成后,在Windows搜索栏中进入“服务”,点击“开始”MySql81。

现在,再试一次,MySQL和Node.js之间的连接应该工作了!

在MySQL 8.0中,caching_sha2_password是默认的认证 而不是mysql_native_password. ...

这个问题中的大多数答案都会导致身份验证机制从caching_sha2_password降级到mysql_native_password。从安全角度来看,这是相当令人失望的。

文档广泛讨论了caching_sha2_password,当然还有为什么它不应该是降级身份验证方法的首选。

因此,我相信Aidin的回答应该是公认的答案。不要降级身份验证方法,而是使用与服务器版本匹配的连接器

在MySQL 8+中,新的默认身份验证是caching_sha2_password而不是mysql_native_password。原生的mysql包还不支持这种新的更安全的身份验证方法,但是您应该考虑使用由Oracle官方支持和维护的@mysql/xdevapi包。

要安装新包,请运行:

npm install @mysql/xdevapi --save --save-exact

连接到数据库并插入一些值:

const mysqlx = require('@mysql/xdevapi');
var myTable;


mysqlx
.getSession({
user: 'root',
password: '*****',
host: 'localhost',
port: 33060
})
.then(function (session) {


// Accessing an existing table
myTable = session.getSchema('Database_Name').getTable('Table_Name');


// Insert SQL Table data
return myTable
.insert(['first_name', 'last_name'])
.values(['John', 'Doe'])
.execute()
});

官方包文档可以在这里找到: # EYZ0 < / p >

在尝试了很多东西之后才发现这一点。最后,我把require('dotenv').config()添加到我的.sequelizerc文件中。显然,sequel -cli不读取env变量。

如果你使用docker,它对我有用!

docker-compose.yml中添加以下行:

mysql:
...
command: --default-authentication-plugin=mysql_native_password
restart: always

然后,down容器和up再次。

除了以上答案; 执行以下命令后

. sh
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'

如果你得到一个错误为:

[ERROR] Column count of mysql.user is wrong. Expected 42, found 44. The table is probably corrupted

然后尝试在cmd作为admin;将路径设置为cmd下的“MySQL server bin”文件夹

set path=%PATH%;D:\xampp\mysql\bin;

然后执行如下命令:

mysql_upgrade --force -uroot -p

这将更新服务器和系统表。

然后,您应该能够成功地在Workbench中的Query中运行以下命令:

 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'

然后记得执行以下命令:

flush privileges;

经过所有这些步骤应该能够成功连接到您的MySQL数据库。

降级可能不是一个好的选择,因为:

  1. 它升级是有原因的(为了提供更好的身份验证)。
  2. 您可能没有足够的权限来进行此类更改。
你可以使用mysql2包来代替mysql包。它的大部分API与mysqljs兼容。 此外,它有承诺支持 像这样使用它: const mysql = require('mysql2/promise')(对于基于承诺的方法)

你可以在这里阅读更多关于mysql2: https://www.npmjs.com/package/mysql2

您可以跳过ORM,构建器等,并使用sqlersqler-mdb简化您的DB/SQL管理。

-- create this file at: db/mdb/read.table.rows.sql
SELECT TST.ID AS "id", TST.NAME AS "name", NULL AS "report",
TST.CREATED_AT AS "created", TST.UPDATED_AT AS "updated"
FROM TEST TST
WHERE UPPER(TST.NAME) LIKE CONCAT(CONCAT('%', UPPER(:name)), '%')
const conf = {
"univ": {
"db": {
"mdb": {
"host": "localhost",
"username":"admin",
"password": "mysqlpassword"
}
}
},
"db": {
"dialects": {
"mdb": "sqler-mdb"
},
"connections": [
{
"id": "mdb",
"name": "mdb",
"dir": "db/mdb",
"service": "MySQL",
"dialect": "mdb",
"pool": {},
"driverOptions": {
"connection": {
"multipleStatements": true
}
}
}
]
}
};


// create/initialize manager
const manager = new Manager(conf);
await manager.init();


// .sql file path is path to db function
const result = await manager.db.mdb.read.table.rows({
binds: {
name: 'Some Name'
}
});


console.log('Result:', result);


// after we're done using the manager we should close it
process.on('SIGINT', async function sigintDB() {
await manager.close();
console.log('Manager has been closed');
});

我也遇到了这个问题,上面提到的所有MySQL重新配置错误仍然出现。结果是我数据库名称拼写错误

因此,请确保您使用正确的数据库名称进行连接,特别是在这种情况下。

这个错误我犯了好几个小时,最后才弄清楚。正如Zchary所说,要非常仔细地检查您传递的数据库名称是否正确。

实际上,在我的情况下,情况更糟:我在所有中传递了我的createConnection()参数作为undefined,因为我从process.env中获取了它们。至少我是这么想的!然后我意识到我的调试和测试npm脚本工作,但事情失败了正常运行。嗯…

所以重点是- MySQL似乎抛出这个错误,即使用户名,密码,数据库和主机字段都是undefined,这是有点误导。

不管怎样,这个故事的士气-先检查愚蠢和看似不可能的事情!

如果你有权限创建一个新的用户权限,然后这样做,以正常连接node.js,这对我来说是有效的

确保你用来访问你的数据库的用户有权限这样做。
# EYZ0
其中第一个星号可以替换为数据库名称,第二个星号指定表。确保在。

后清除特权

最简单的答案是:-

  1. 在节点中使用mysql2代替mysql

在节点中安装mysql2

  1. # EYZ0 < br >

不要降级你的mysql数据库。

你很好。 编码快乐!< / >强

我建议使用< >强Knexjs < / >强< >强MySQL2 < / >强

你有很好的去caching_sha2_password认证方法。

使用Knex查询:

const response = await knex.raw("SELECT * FROM USERS");

如果您没有远程用户,则使用CREATE关键字而不是ALTER,并在终端上输入以下命令。

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'@'%';
Flush privileges;


ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpass';
GRANT ALL ON *.* TO 'root'@'localhost';
Flush privileges;

全部完成:)

UPDATE mysql.user SET authentication_string = PASSWORD('MY_NEW_PASSWORD')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;

这对我很管用。

对于MySql 8,不改变用户的认证,而是创建一个新的用户用户,并将认证方法从caching_sha2_password更改为mysql_native_password。 详细步骤请查看Ochuko Ekrresa的文档

步骤总结:

  1. 以root用户mysql -u root -p登录
  2. 创建新用户CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
  3. 宏大,所有权限GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'localhost';

请检查上述文档链接,以获得有关授予特定特权的详细信息。

  1. 重新加载权限FLUSH PRIVILEGES;
  2. 退出MySql quit;,重新登录mysql -u [newuser] -p;
  3. 最后一步更改身份验证ALTER USER 'newuser'@'localhost' IDENTIFIED WITH mysql_native_password by 'password';
< p >额外的信息: 对于我来说,在将身份验证更改为root后,我面临身份验证问题,无法登录。所以我重置我的密码(重置密码文档).

对于会话,您应该使用用于mysql连接的任何模式

(async () => {
const connection = await db.connection();
sessionStore = new MySQLStore({


}, connection); //just pass your connection here
})();


我只是复制粘贴到这里但你可能已经实现了类似的东西来处理你的查询

const mysql = require('mysql')


if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') {
require('dotenv').config();
}


const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
connectionLimit: process.env.DB_CONNECTION_LIMITS
}


const pool = mysql.createPool(dbConfig);


const connection = () => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
reject(err);
}


const query = (sql, binding) => {
return new Promise((resolve, reject) => {
connection.query(sql, binding, (err, result) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};


const release = () => {
return new Promise((resolve, reject) => {
if (err) {
reject(err);
}
resolve(connection.release());
});
};
resolve({ query, release });
});
});
};


const query = (sql, binding) => {
return new Promise((resolve, reject) => {
pool.query(sql, binding, (err, result, fields) => {
if (err) {
reject(err);
}
resolve(result);
});
});
};


module.exports = { pool, connection, query };


简单i 卸载mysql安装mysql2为这个问题和 问题解决了。< / p >

npm uninstall mysql && npm i mysql2