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

时间:2018-04-30 02:04:32

标签: mysql node.js

我是node.js和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 https://github.com/mysqljs/mysql/issues/1507

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

29 个答案:

答案 0 :(得分:263)

在MYSQL Workbench中执行以下查询

ALTER USER'root'@'localhost'用mysql_native_password识别BY'密码'

尝试使用节点连接

答案 1 :(得分:44)

使用旧的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版本。您可以查看this pull requestthis issue了解更多信息。可能很快就会有修复程序!

答案 2 :(得分:9)

尽管接受的答案是正确的,但我还是希望创建一个新用户,然后使用该用户访问数据库。

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';

答案 3 :(得分:9)

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

MySQL 8支持可插入身份验证方法。默认情况下,将使用其中一个名为caching_sha2_password的名称,而不是我们的旧版本mysql_native_passwordsource)。很明显,使用具有多次握手功能的加密算法比24 years上的普通密码传递更安全!

现在,问题出在Node中的mysqljs(您用npm i mysql安装的软件包并在Node代码中使用了该软件包)尚不支持MySQL 8的这种新的默认身份验证方法。问题出在这里:https://github.com/mysqljs/mysql/issues/1507,并在3年​​后的2019年7月仍然开放。(2019年6月更新:现在有new PR in mysqljs可以解决此问题!)

您的选项

选项1)使用旧的“ native_password”降级“ MySQL”以进行身份​​验证

这就是每个人的建议(例如top answer above)。您只需进入mysql并运行一个查询,说使用旧的root方法进行身份验证即可使用native_password

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

好处是,生活会变得很简单,您仍然可以使用没有any issue的旧工具,例如Sequel Pro。但是问题是,您没有利用向您提供的更安全(并且很酷,请参阅下文)的东西。

选项2)将“ Node”包替换为MySQL Connecter X DevAPI

MySQL X DevAPI for NodeNode's Mysqljs package官方提供的http://dev.mysql.com的替代品。

它像支持caching_sha2_password身份验证的超级按钮一样工作。 (只需确保将端口33060用于X Protocol commmunications。)

不好的是,您已经离开了每个人都习惯并依赖的旧mysql包。

好消息是,您的应用程序现在更安全了,您可以利用我们的好朋友没有提供的大量新功能!只需检查一下tutorial of X DevAPI,您就会发现它具有大量方便使用的新性感功能。您只需要付出学习曲线的代价即可,任何技术升级都可能附带该曲线。 :)

PS。不幸的是,这个XDevAPI包还没有类型定义(TypeScript可以理解),因此,如果您使用的是 typescript ,则会遇到问题。我尝试使用dts-gendtsmake生成.d.ts,但没有成功。所以请记住这一点。

干杯!

答案 4 :(得分:8)

最简单的答案是:-

  1. 在节点中使用 mysql2 而不是 mysql

在节点上安装mysql2

  1. npm 安装 mysql2

不要降级你的 mysql 数据库。

你可以走了。 快乐编码!

答案 5 :(得分:7)

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

然后尝试使用节点进行连接

答案 6 :(得分:5)

在Mysql最新的docker容器中

ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';

答案 7 :(得分:3)

如果您使用的是docker,它对我有用!

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

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

之后,down容器,然后再次up

答案 8 :(得分:3)

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

要安装新软件包,请运行:

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()
    });

官方软件包的文档可以在这里找到: https://dev.mysql.com/doc/dev/connector-nodejs/8.0/

答案 9 :(得分:2)

我在服务器上有MYSQL,在另一台服务器上有nodejs应用程序

在MYSQL Workbench中执行以下查询

使用mysql_native_password通过'password'标识ALTER USER'root'@'%'

答案 10 :(得分:2)

如果ALTER USER ...命令行对您不起作用,并且您使用的是Windows 10,请尝试执行以下步骤:

1)在Windows搜索栏中输入MySQL

2)打开MySQL Windows Installer-社区

3)查找“ MySQL服务器”,然后单击“重新配置” step 3

4)单击“下一步”,直到进入“身份验证方法”阶段

5)在“身份验证方法”阶段,选中第二个选项“使用旧版身份验证方法” step 5

6)然后按照Windows安装程序给出的步骤进行操作

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

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

答案 11 :(得分:2)

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

  1. 出于某种原因对其进行了升级(以提供更好的身份验证)。
  2. 您可能没有足够的权限进行此类更改。

您可以使用mysql2软件包代替mysql。它的大多数API与mysqljs兼容。 另外,它有希望的支持。

使用方式如下: const mysql = require('mysql2/promise')(用于基于承诺的方法)

您可以在此处了解有关mysql2的更多信息:https://www.npmjs.com/package/mysql2

希望有帮助。 :)

答案 12 :(得分:1)

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

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中尝试;在cmd中设置MySQL服务器bin文件夹的路径

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

然后运行命令:

mysql_upgrade --force -uroot -p

这应该更新服务器和系统表。

然后,您应该能够在工作台的查询中成功运行以下命令:

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

然后记住执行以下命令:

flush privileges;

完成所有这些步骤之后,便应该能够成功连接到您的MySQL数据库。 希望这会有所帮助...

答案 13 :(得分:1)

  

在MySQL 8.0中,caching_sha2_password是默认身份验证   插件而不是mysql_native_password. ...

该问题中的大多数答案都将认证机制从caching_sha2_password降级为mysql_native_password。从安全角度来看,这非常令人失望。

This文档广泛讨论了caching_sha2_password,当然也讨论了为什么不应该将其降级为首选方法。

基于此,我认为爱丁的answer应该是公认的答案。与其降低身份验证方法的等级,不如使用与服务器版本匹配的connector

答案 14 :(得分:1)

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

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

答案 15 :(得分:1)

我建议将 KnexjsMySQL2 一起使用。

而且您很高兴使用 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;

全部完成:)

答案 16 :(得分:1)

对于 MySql 8,不是更改 root 用户的身份验证,而是创建一个具有所有权限的新 用户,并将身份验证方法从 caching_sha2_password 更改为 mysql_native_password。 请查看 Ochuko Ekrresa 撰写的 documentation 以了解详细步骤。

步骤摘要:

  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';

附加信息: 对我来说,在更改 root 的身份验证后,我遇到了身份验证问题并且无法登录。所以我重置了我的密码(Reset password doc)。

答案 17 :(得分:1)

如果遇到此错误,但仍要使用MySQL版本8,则可以通过使用Docker创建数据库时告诉MySQL服务器使用旧版身份验证插件来实现。

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

# 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

答案 18 :(得分:1)

对于在Windows 10 mysql上安装的现有mysql 8.0,(1)启动安装程序, (2)在QuickAction(位于MySQL服务器的左侧)1下单击“重新配置”,然后 (3)单击“下一步”前进到接下来的两个屏幕,直到到达 (4)在“身份验证方法”处,选择“使用旧版身份验证方法(保持MySQL 5.x兼容性)2(5)持续单击直到安装完成

答案 19 :(得分:1)

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

<access sslFlags="Ssl.SslRequireCert,SslNegotiateCert,Ssl128" />

答案 20 :(得分:0)

在尝试了无数次尝试之后才弄清楚了这一点。最终对我来说是将require('dotenv').config()添加到我的.sequelizerc文件中。显然,sequelize-cli无法读取环境变量。

答案 21 :(得分:0)

检查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!");
});

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

答案 22 :(得分:0)

您可以跳过sqlersqler-mdb来跳过ORM,构建器等,并简化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');
});

答案 23 :(得分:0)

我有几个小时的错误了,直到最后。正如Zchary所说,请非常仔细地检查您是否输入了正确的数据库名称。

实际上,就我而言,情况甚至更糟:我将createConnection()的所有参数undefined作为process.env传入,因为我是从{{1} }。还是我想!然后我意识到我的调试和测试npm脚本可以工作,但是正常运行失败。嗯...

因此,重点是-即使用户名,密码,数据库和主机字段均为undefined,MySQL似乎仍会引发此错误,这会引起误解。

无论如何,故事的士气-首先检查愚蠢的,看似不太可能的事情!

答案 24 :(得分:0)

如果您有权创建新的用户权限,则可以正常连接到node.js,这对我有用

答案 25 :(得分:0)

确保用于访问数据库的用户具有这样做的特权。
string SQL = @" WITH cte AS ( SELECT TOP 5 QuestionId FROM Questions ORDER BY NEWID() ) SELECT QuestionText,CorrectAnswer,WrongAnswer1,WrongAnswer2,WrongAnswer3 FROM cte c JOIN Questions q ON q.QuestionId = c.QuestionId ";
第一个星号可以用数据库名称代替,第二个星号指定表。确保之后刷新特权。

答案 26 :(得分:0)

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

LiveData

答案 27 :(得分:0)

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

这对我有用。

答案 28 :(得分:0)

只需运行MySQL Server安装程序并重新配置My SQL Server ...这对我有用。