MySQL 8.0 - Máy khách không hỗ trợ giao thức xác thực do máy chủ yêu cầu; xem xét nâng cấp máy khách MySQL


274

Tôi không thể thực hiện một kết nối đơn giản đến máy chủ vì một số lý do. Tôi cài đặt cơ sở dữ liệu MySQL Community 8.0 mới nhất cùng với Node.JS với cài đặt mặc định.

Đây là mã node.js của tôi

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

Dưới đây là lỗi được tìm thấy trong Dấu nhắc lệnh:

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)

Tôi đã đọc về một số thứ như: https://dev.mysql.com/doc/refman/5.5/en/old-client.html https://github.com/mysqljs/mysql/issues/1507

Nhưng tôi vẫn không chắc chắn làm thế nào để khắc phục vấn đề của tôi. Bất kỳ trợ giúp sẽ được đánh giá cao: D


2
Tất cả người dùng VS Code sử dụng tiện ích mở rộng SQLTools nên tham khảo bài đăng này trong trường hợp họ gặp sự cố với điều này, đặc biệt nếu bạn vừa nâng cấp phiên bản mysql trên máy tính phát triển của mình
OzzyTheGiant

Câu trả lời:


679

Thực hiện truy vấn sau trong MYSQL Workbench

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

Người rootdùng của bạn localhostlà URL và passwordmật khẩu của bạn ở đâu

Sau đó chạy truy vấn này để làm mới đặc quyền:

flush privileges;

Hãy thử kết nối bằng nút sau khi bạn làm như vậy.

Nếu nó không hoạt động, hãy thử nó mà không có @'localhost'phần.


47
Điều này làm việc cho tôi. Đừng quên flush privileges;sau.
Ali Hesari

12
Nó hoạt động với tôi mà không có @localhost (tôi đoán có thể là vì nó không dành cho người dùng root)
NicolasZ

10
thay thế 'mật khẩu' bằng mật khẩu gốc của bạn nếu bạn biết nó
Vedha Peri

11
Nó hoạt động ...... nhưng tại sao nó không hoạt động trước đó và tại sao nó hoạt động sau truy vấn này vẫn còn là một câu hỏi.
saksham

9
Xin chào @GuilhermeMatuella Điều này là do caching_sha2_passwordđược giới thiệu trong MySQL 8.0, nhưng phiên bản Node.js chưa được triển khai.
Daksh Gargas

108

Trước tiên hãy làm rõ những gì đang diễn ra.

MySQL 8 đã hỗ trợ các phương thức xác thực có thể cắm. Theo mặc định, một trong số chúng được đặt tên caching_sha2_passwordđược sử dụng thay vì tốt mysql_native_password( nguồn ) cũ của chúng tôi . Rõ ràng là sử dụng thuật toán mật mã với một vài cái bắt tay sẽ an toàn hơn so với việc chuyển mật khẩu đơn giản đã tồn tại trong 24 năm !

Bây giờ, vấn đề nằm mysqljsở Node (gói bạn cài đặt npm i mysqlvà sử dụng nó trong mã Node của bạn) chưa hỗ trợ phương thức xác thực mặc định mới này của MySQL 8. Vấn đề nằm ở đây: https://github.com/mysqljs/mysql/issues/1507 và vẫn mở, sau 3 năm, kể từ tháng 7 năm 2019.

(CẬP NHẬT tháng 6 năm 2019: Hiện tại đã có một PR mới trong mysqljs để khắc phục điều này! ) (CẬP NHẬT tháng 2 năm 2020: Rõ ràng nó đã được lên kế hoạch để đến trong phiên bản 3 của mysqljs . )

Lựa chọn của bạn

Tùy chọn 1) Hạ cấp "MySQL" để xác thực bằng cách sử dụng "local_password" cũ

Đó là những gì mọi người gợi ý ở đây (ví dụ câu trả lời hàng đầu ở trên ). Bạn chỉ cần mysqltruy cập và chạy một truy vấn cho biết rootlà sử dụng native_passwordphương thức cũ để xác thực quyền:

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

Điều tốt là, cuộc sống sẽ trở nên đơn giản và bạn vẫn có thể sử dụng các công cụ cũ tốt như Sequel Pro mà không gặp vấn đề gì . Nhưng vấn đề là, bạn không tận dụng được những thứ an toàn hơn (và tuyệt vời, đọc bên dưới) có sẵn cho bạn.

Tùy chọn 2) Thay thế gói "Nút" bằng MySQL Connecter X DevAPI

MySQL X DevAPI cho Node là sự thay thế cho gói Mysqljs của Node , được cung cấp bởi http://dev.mysql.com .

Nó hoạt động như một sự quyến rũ hỗ trợ caching_sha2_passwordxác thực. (Chỉ cần đảm bảo rằng bạn sử dụng cổng 33060cho giao tiếp X Protocol .)

Điều tồi tệ là, bạn đã rời khỏi mysqlgói cũ của chúng tôi mà mọi người đã quá quen thuộc và dựa vào.

Điều tốt là, ứng dụng của bạn hiện an toàn hơn và bạn có thể tận dụng hàng tấn những thứ mới mà những người bạn cũ tốt của chúng tôi không cung cấp! Chỉ cần xem hướng dẫn của X DevAPI và bạn sẽ thấy nó có vô số tính năng gợi cảm mới có thể có ích. Bạn chỉ cần trả giá của một đường cong học tập, dự kiến ​​sẽ đi kèm với bất kỳ nâng cấp công nghệ. :)

Tái bút Thật không may, Gói XDevAPI này chưa có định nghĩa loại (có thể hiểu được bởi TypeScript), vì vậy nếu bạn đang ở trên bản in , bạn sẽ gặp vấn đề. Tôi đã cố gắng tạo .d.ts bằng cách sử dụng dts-gendtsmake, nhưng không thành công. Vì vậy, hãy ghi nhớ điều đó.

Chúc mừng!


3
Cảm ơn đã đăng một câu trả lời chi tiết cho một câu hỏi cũ. :]
Daksh Gargas

3
thật tuyệt, một câu trả lời thực sự giải thích cho mysql_native_password thay vì chỉ bảo bạn làm điều đó
wizloc

1
Vâng, một lời giải thích thích hợp cho một lần. Tốt cho bạn Aidin. Làm thế nào tôi muốn kết nối các ứng dụng không tự động cấu hình cổng 3306 với MySQL. Chúng tôi có đủ rắc rối để đánh giá MySQL và MariaDB từ năm 3306.
Trunk

Hãy cẩn thận với các plugin của Oracle, bạn có thể bị phạt rất lớn: theregister.co.uk/2019/10/04/oracle_virtualbox_merula
Juha Untinen

Đây là một câu trả lời tuyệt vời xứng đáng nhận được nhiều hơn!
Tháng Sáu Wenston

82

Sử dụng các mysql_native_passwordcông trình cũ :

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;

Điều này là do caching_sha2_passwordđược giới thiệu trong MySQL 8.0, nhưng phiên bản Node.js chưa được triển khai. Bạn có thể xem yêu cầu kéo nàyvấn đề này để biết thêm thông tin. Có lẽ một sửa chữa sẽ đến sớm!


Làm việc như một cơ duyên. Thật là nhẹ nhõm!

sự khác biệt giữa việc thêm @localhost và chỉ 'root'
filemonchot

Truy vấn hoạt động. Nhưng nút vẫn không thể kết nối với máy chủ MySQL. Bất kỳ ý tưởng? Đây là lỗi, {"code": "ER_ACCESS_DENIED_ERROR", "errno": 1045, "sqlMessage": "Truy cập bị từ chối cho người dùng 'root' @ 'localhost' (sử dụng mật khẩu: YES)", "sqlState": "28000" , "gây tử vong": đúng}
Sanjay Pradeep

26

Các bước đầy đủ cho MySQL 8

Kết nối với MySQL

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

Đặt lại mật khẩu của bạn

(Thay thế your_new_passwordbằng mật khẩu bạn muốn sử dụng)

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

Sau đó thử kết nối bằng nút


@sky xem câu trả lời của tôi ở trên để biết chi tiết.
Aidin

1
@Aidin Cảm ơn, nó rất hữu ích.
Bầu trời

17

Mặc dù câu trả lời được chấp nhận là chính xác, tôi muốn tạo một người dùng mới và sau đó sử dụng người dùng đó để truy cập cơ sở dữ liệu.

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

2
Nếu ai đó muốn đi theo con đường này, đây là một bài viết với một số lời giải thích: digitalocean.com/community/tutorials/ mẹo
Devin

12

Nếu bạn gặp phải lỗi này nhưng vẫn muốn sử dụng MySQLphiên bản 8. Bạn có thể đạt được điều này bằng cách yêu cầu Máy chủ MySQL sử dụng plugin xác thực cũ khi bạn tạo cơ sở dữ liệu bằng cách sử dụng Docker.

Vì vậy, composetập tin của bạn sẽ trông như thế này:

# 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

Tôi đang sử dụng commandnhưng vẫn nhận được thông báo lỗi xác thực không được hỗ trợ khi sử dụng mysqltrong Node.js
Juha Untinen

Stacktrace đầy đủ là ở đây: pastebin.com/SzayQzdhDocker-compose.yml : pastebin.com/7pUrWYDs Các lỗi chính nó là:Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Juha Untinen

1
@JuhaUntinen đảm bảo rằng bạn đã xóa bộ chứa Docker (bộ chứa được tạo bởi docker-compose) và âm lượng (~ / Database / ORM_Test) và sau đó chạy lại 'docker-compose up'. Nếu không, những thay đổi từ 'lệnh' sẽ không được áp dụng. Nó giúp trong trường hợp của tôi.
Vitalii Ivanov

11

Trong Mysql Container docker mới nhất

ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';

9

Nếu dòng lệnh ALTER USER ... không hoạt động với bạn VÀ nếu bạn đang sử dụng Windows 10 thì hãy thử làm theo các bước sau:

1) Nhập MySQL vào thanh tìm kiếm của windows

2) Mở Trình cài đặt Windows của MySQL - Cộng đồng

3) Tìm "Máy chủ MySQL" và nhấp vào Cấu hình lại bước 3

4) Nhấp vào "Tiếp theo" cho đến khi bạn đạt đến giai đoạn "Phương thức xác thực"

5) Trong giai đoạn "Phương thức xác thực", hãy kiểm tra tùy chọn thứ hai "Sử dụng phương thức xác thực kế thừa" bước 5

6) Sau đó làm theo các bước được cung cấp bởi trình cài đặt Windows cho đến khi kết thúc

7) Khi hoàn tất, hãy vào "Dịch vụ" từ thanh tìm kiếm của Windows, nhấp vào "bắt đầu" MySql81 ".

Bây giờ, hãy thử lại, kết nối giữa MySQL và Node.js sẽ hoạt động!


4

Trong MySQL 8.0, caching_sha2_passwordlà plugin xác thực mặc định chứ không phải là pluginmysql_native_password. ...

Hầu hết các câu trả lời trong câu hỏi này dẫn đến việc hạ cấp xuống cơ chế xác thực từ caching_sha2_passwordđến mysql_native_password. Từ góc độ bảo mật, điều này khá đáng thất vọng.

Tài liệu này thảo luận rộng rãi caching_sha2_passwordvà tất nhiên tại sao KHÔNG nên là lựa chọn đầu tiên để hạ cấp phương thức xác thực.

Với điều đó, tôi tin rằng câu trả lời của Aidin nên là câu trả lời được chấp nhận. Thay vì hạ cấp phương thức xác thực, thay vào đó hãy sử dụng trình kết nối khớp với phiên bản của máy chủ.


3

Tài liệu gốc bạn có thể tìm thấy ở đây: 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);
  });

Có vẻ phức tạp hơn, nhưng tôi nghĩ chúng ta nên làm theo hướng dẫn chính thức! b
Juneyoung Oh

3

Tôi có MYSQL trên máy chủ và ứng dụng nodejs trên máy chủ khác

Thực hiện truy vấn sau trong MYSQL Workbench

THAY ĐỔI NGƯỜI DÙNG 'root' @ '%' XÁC NHẬN VỚI mysql_native_password B'NG 'mật khẩu'


2

Đối với các bản cài đặt mysql 8.0 hiện có trên Windows 10 mysql,

(1) khởi chạy trình cài đặt,

(2) nhấp vào "Định cấu hình lại" trong QuickAction (ở bên trái Máy chủ MySQL), sau đó

(3) nhấp vào tiếp theo để xem qua 2 màn hình tiếp theo cho đến khi đến

(4) tại "Phương thức xác thực", chọn "Sử dụng phương thức xác thực kế thừa (Giữ lại khả năng tương thích MySQL 5.x"

(5) Tiếp tục nhấp cho đến khi cài đặt hoàn tất


2

Với MySQL 8+, xác thực mặc định mới là caching_sha2_passwordthay thế mysql_native_password. Phương thức xác thực mới và an toàn hơn chưa được hỗ trợ bởi mysqlgói gốc , nhưng bạn nên xem xét sử dụng gói @mysql/xdevapithay thế, được Oracle hỗ trợ và duy trì chính thức.

Để cài đặt gói mới, hãy chạy:

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

Để kết nối với cơ sở dữ liệu và XÁC NHẬN một số GIÁ TRỊ:

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

Tài liệu gói chính thức có thể được tìm thấy ở đây: https://dev.mysql.com/doc/dev/connector-nodejs/8.0/


2

Nếu bạn đang sử dụng docker, nó làm việc cho tôi!

trong phần docker-compose.ymlthêm các dòng sau:

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

Sau đó, downcontainer và upmột lần nữa.


1

Ngoài các câu trả lời trên; Sau khi thực hiện lệnh dưới đây

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

Nếu bạn gặp lỗi như:

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

Sau đó thử trong cmd với tư cách quản trị viên; đặt đường dẫn đến thư mục bin máy chủ MySQL trong cmd

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

và sau đó chạy lệnh:

mysql_upgrade --force -uroot -p

Điều này sẽ cập nhật máy chủ và các bảng hệ thống.

Sau đó, bạn sẽ có thể chạy thành công các lệnh bên dưới trong Truy vấn trong Bàn làm việc:

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

sau đó nhớ thực hiện lệnh sau:

flush privileges;

Sau tất cả các bước này sẽ có thể kết nối thành công với cơ sở dữ liệu MySQL của bạn. Hi vọng điêu nay co ich...


0

Chỉ cần chạy Trình cài đặt máy chủ MySQL và cấu hình lại máy chủ SQL của tôi ... Điều này hiệu quả với tôi.


0

Kiểm tra đặc quyền và tên người dùng / mật khẩu cho người dùng MySQL của bạn.

Để bắt lỗi, luôn hữu ích khi sử dụng _delegateErrorphương thức ghi đè . Trong trường hợp của bạn, điều này phải giống như:

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

Cấu trúc này sẽ giúp bạn theo dõi các lỗi nghiêm trọng.


0

Chỉ cần tìm ra điều này sau khi thử nhiều thứ. Điều cuối cùng đã làm cho tôi là thêm require('dotenv').config()vào .sequelizerctập tin của tôi . Rõ ràng sequelize-cli không đọc các biến env.


0

Phân loại xuống có thể không phải là một lựa chọn tốt như:

  1. Nó được nâng cấp vì một lý do (Để cung cấp xác thực tốt hơn).
  2. Bạn có thể không có đủ quyền để thực hiện các thay đổi đó.

Bạn có thể sử dụng mysql2gói thay thế mysql. API chủ yếu tương thích với mysqljs. Ngoài ra, nó có lời hứa hỗ trợ.

Sử dụng nó như: const mysql = require('mysql2/promise')

Bạn có thể đọc thêm về mysql2đây: https://www.npmjs.com/package/mysql2

Hy vọng nó giúp. :)


0

Bạn có thể bỏ qua ORM, trình xây dựng, v.v. và đơn giản hóa việc quản lý DB / SQL của bạn bằng cách sử dụng sqlersqler-mdb.

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

-1

Tôi có cùng một vấn đề với MySQL và tôi giải quyết bằng cách sử dụng XAMPP để kết nối với MySQL và dừng các dịch vụ trong windows cho MySQL (bảng điều khiển - Công cụ quản trị - Dịch vụ) và trong thư mục db.js (chịu trách nhiệm về cơ sở dữ liệu) I làm cho mật khẩu trống (ở đây bạn có thể thấy :)

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

xin vui lòng không thêm một vấn đề mà bạn đang phải đối mặt như một câu trả lời cho vấn đề phải đối mặt
Aloy A Sen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.