Node.js 无法对 MySQL 8.0 进行身份验证。

32

我有一个Node.js程序,使用root账户连接到本地的MySQL数据库(这不是生产环境)。 这是创建连接的代码:

const mysql = require('mysql');

const dbConn = mysql.createConnection({
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: 'myRootPassword',
    database: 'decldb'
});

dbConn.connect(err => {
    if (err) throw err;
    console.log('Connected!');
});

在使用MySQL 5.7时它可以工作,但自从安装了MySQL 8.0后,在启动Node.js应用程序时出现了这个错误:

> node .\api-server\main.js
[2018-05-16T13:53:53.153Z] Server launched on port 3000!
C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Parser.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\me\project\node_server\node_modules\mysql\lib\protocol\sequences\Sequence.js:52:14)
    at Handshake.ErrorPacket (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\sequences\Handshake.js:130:18)
    at Protocol._parsePacket (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Protocol.js:279:23)
    at Parser.write (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Parser.js:76:12)
    at Protocol.write (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Protocol.js:39:16)
    at Socket.<anonymous> (C:\Users\me\project\node_server\node_modules\mysql\lib\Connection.js:103:28)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    --------------------
    at Protocol._enqueue (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Protocol.js:145:48)
    at Protocol.handshake (C:\Users\me\project\node_server\node_modules\mysql\lib\protocol\Protocol.js:52:23)
    at Connection.connect (C:\Users\me\project\node_server\node_modules\mysql\lib\Connection.js:130:18)
    at Object.<anonymous> (C:\Users\me\project\node_server\main.js:27:8)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Function.Module.runMain (module.js:693:10)

看起来root帐户使用了一种新的密码散列方法:

> select User,Host,plugin from user where User="root";
+------+-----------+-----------------------+
| User | Host      | plugin                |
+------+-----------+-----------------------+
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+

...但我不知道为什么Node.js无法连接它。我已经更新了所有的npm包,但问题仍然存在。

我想保留新的密码哈希方法。我还能让这个连接工作吗?我需要等待MySQL Node.js包的更新,还是需要在我的端上更改设置?


你尝试在连接中指定端口了吗? - Fernando Paz
@FernandoPaz 我刚刚尝试了一下,问题还是存在。 - Hey
1
这同样影响到了PHP的PDO。被接受的答案也修复了它。 - Nigel Atkinson
您可以在此频道查找更多答案:https://dev59.com/plUL5IYBdhLWcg3wmpDH#56752560 - Campalo
5个回答

66
MySQL 8.0使用新的默认身份验证插件caching_sha2_password,而MySQL 5.7使用了不同的插件mysql_native_password。目前,MySQL的社区Node.js驱动程序不支持新服务器插件的兼容客户端身份验证机制。
一种可能的解决方法是更改用户帐户类型以使用旧的身份验证插件:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MyNewPass';

或者创建一个使用相同插件的不同插件:

CREATE USER 'foo'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bar';

在流程中有一个拉取请求来正确解决这个问题。

另一个选项是使用官方的MySQL Node.js连接器(完全透明:我是首席开发人员),它基于X协议,已经支持新的认证模式。


谢谢你的回答,第二种方法对我有用。我想知道为什么第一种方法即“alter user”会显示错误:“操作ALTER USER失败,针对'root'@'localhost'”。 - Pranjal Gupta
也许某些客户端选项正在阻止您覆盖“root”权限。如果没有更好的上下文,我不是完全确定。也许您可以在此处找到答案:https://dev.mysql.com/doc/refman/8.0/en/resetting-permissions.html。 - ruiquelhas
1
使用新连接器的标准查询是否有文档可供参考?我一直在研究这个问题,但我对文档存储不感兴趣。我只是想像标准库那样构建一个查询并执行它。我发现会话对象非常令人困惑。 - sixstring
关于您提到的另一点,Session 对象主要是对数据库连接的抽象,尚未绑定到任何模式、表或集合,这意味着使用 Session.sql() API 运行查询是没有限制的正确方式。 - ruiquelhas
1
我刚在 https://dev59.com/plUL5IYBdhLWcg3wmpDH#56509065 中回答了同样的问题,并提供了更多细节,为 X DevAPI 宣传!做得好 @ruiquelhas :) - Aidin
显示剩余2条评论

5

不需要按照其他答案所建议的更改密码加密方式,你只需要更新你的 npm 包到mysql2即可:

const mysql = require('mysql2');

它支持MySQL 8.0的新默认身份验证插件 - caching_sha2_password。

1
这是不正确的,因为它目前还不支持。请参考此链接:https://github.com/sidorares/node-mysql2/issues/1248#issuecomment-1637257814。 - undefined
已更正答案。感谢您的指正。请现在删除评论。 - undefined
答案是如何更正的?目前看来仍然没有得到支持,这使得答案不准确。 - undefined

0
一个解决方法: 使用mysql_native_password协议创建一个新用户:
CREATE USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'userpassword';

然后为用户授予数据库权限:

 GRANT ALL PRIVILEGES ON userdb.* TO 'dgtong'@'localhost';

0

既然这不是一个生产程序,如果其他(更好的)答案不适合您的情况,使用传统密码加密安装MySQL也可能起到作用。

MySQL 8.0.31 Installation Configuration


0
不要动root账户。创建一个使用“标准”身份验证类型的新用户。根据用户的能力赋予适当的权限。在连接配置中使用该用户及其密码。

嗨,这是一个非常过时的问题,而且已经解决了。无论如何,更新的库可以轻松完成工作。 - pierpy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接