MySQL 8.0 - Klient nie obsługuje protokołu uwierzytelnienia żądanego przez serwer; rozważ aktualizację klienta MySQL

272

Z jakiegoś powodu nie mogę nawiązać prostego połączenia z serwerem. Instaluję najnowszą bazę danych MySQL Community 8.0 wraz z Node.JS z ustawieniami domyślnymi.

To jest mój kod 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!");
    });

Poniżej znajduje się błąd znaleziony w wierszu polecenia:

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)

Przeczytałem o niektórych rzeczach, takich jak: https://dev.mysql.com/doc/refman/5.5/en/old-client.html https://github.com/mysqljs/mysql/issues/1507

Ale nadal nie jestem pewien, jak rozwiązać mój problem. Każda pomoc byłaby mile widziana: D

Świnia
źródło
2
Wszyscy użytkownicy VS Code, którzy używają rozszerzenia SQLTools, powinni odnieść się do tego postu na wypadek, gdyby mieli z tym problem, szczególnie jeśli właśnie zaktualizowaliście instancję mysql na swoim komputerze programistycznym
OzzyTheGiant

Odpowiedzi:

677

Wykonaj następujące zapytanie w MYSQL Workbench

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

Gdzie rootjako użytkownik localhostjako adres URL i passwordhasło

Następnie uruchom to zapytanie, aby odświeżyć uprawnienia:

flush privileges;

Spróbuj to zrobić za pomocą węzła.

Jeśli to nie zadziała, spróbuj bez @'localhost'części.

Pras
źródło
47
To zadziałało dla mnie. Nie zapomnij flush privileges;później.
Ali Hesari,
12
To działało dla mnie bez @localhost (chyba tak może być, ponieważ nie było dla użytkownika root)
NicolasZ 16.08.18
10
zamień hasło na hasło root, jeśli je znasz
Vedha Peri,
11
Działa ...... ale dlaczego wcześniej nie działało i dlaczego działało po tym zapytaniu, wciąż pozostaje pytaniem.
saksham
9
Cześć @ GuilhermeMatuella To dlatego, że caching_sha2_passwordzostał wprowadzony w MySQL 8.0, ale wersja Node.js nie jest jeszcze zaimplementowana.
Daksh Gargas
106

Najpierw wyjaśnijmy, co się dzieje.

MySQL 8 obsługuje metody uwierzytelniania z możliwością podłączenia. Domyślnie caching_sha2_passwordużywany jest jeden z nich o nazwie, a nie nasz stary dobry mysql_native_password( źródło ). Powinno być oczywiste, że użycie algorytmu kryptograficznego z kilkoma uściskami dłoni jest bezpieczniejsze niż zwykłe przekazywanie hasła, które istnieje od 24 lat !

Teraz problem występuje mysqljsw węźle (pakiet, który instalujesz npm i mysqli używasz go w kodzie węzła), nie obsługuje jeszcze tej nowej domyślnej metody uwierzytelniania MySQL 8. Problem znajduje się tutaj: https://github.com/mysqljs/mysql/issues/1507 i jest nadal otwarty po 3 latach od lipca 2019 r.

(AKTUALIZACJA czerwiec 2019: W mysqljs jest teraz nowy PR, aby to naprawić! ) (AKTUALIZACJA luty 2020: Najwyraźniej planowane jest wydanie wersji 3 mysqljs . )

Twoje opcje

Opcja 1) Zmień wersję „MySQL” w celu uwierzytelnienia przy użyciu starego, dobrego „hasła natywnego”

To wszyscy sugerują tutaj (np. Najwyższa odpowiedź powyżej ). Wystarczy wejść mysqli uruchomić kwerendę mówiąc rootjest w porządku stosując starą native_passwordmetodę authnetication:

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

Dobrą rzeczą jest to, że życie będzie proste i nadal będziesz mógł używać starych dobrych narzędzi, takich jak Sequel Pro, bez żadnych problemów . Ale problem polega na tym, że nie korzystasz z bezpieczniejszych (i fajnych, przeczytaj poniżej) rzeczy dostępnych dla ciebie.

Opcja 2) Zamień pakiet „Węzeł” na MySQL Connecter X DevAPI

MySQL X DevAPI for Node jest zamiennikiem pakietu Mysqljs firmy Node , udostępnionego przez oficjalnych facetów http://dev.mysql.com .

Działa jak urok wspierający caching_sha2_passworduwierzytelnianie. (Upewnij się tylko, że używasz portu 33060do komunikacji X Protocol ).

Złe jest to, że opuściłeś nasz stary mysqlpakiet, do którego wszyscy są przyzwyczajeni.

Dobrą rzeczą jest to, że Twoja aplikacja jest teraz bezpieczniejsza i możesz skorzystać z mnóstwa nowych rzeczy, których nie dostarczali nasi starzy dobrzy przyjaciele! Wystarczy zapoznać się z samouczkiem X DevAPI, a zobaczysz, że ma mnóstwo nowych seksownych funkcji, które mogą się przydać. Trzeba tylko zapłacić cenę za krzywą uczenia się, która prawdopodobnie pojawi się wraz z każdą aktualizacją technologii. :)

PS. Niestety ten pakiet XDevAPI nie ma jeszcze definicji typów (zrozumiałej dla TypeScript), więc jeśli używasz maszynopisu , będziesz mieć problemy. Próbowałem wygenerować .d.ts przy użyciu dts-geni dtsmake, ale bez powodzenia. Miej to na uwadze.

Twoje zdrowie!

Aidin
źródło
3
Dziękujemy za opublikowanie szczegółowej odpowiedzi na roczne pytanie. :]
Daksh Gargas
3
fajnie, odpowiedź, która faktycznie tłumaczy mysql_native_password zamiast po prostu kazać ci to zrobić
wizloc
1
Tak, choć raz właściwe wyjaśnienie. Dobrze dla ciebie, Aidin. Chciałbym, aby aplikacje łączące się nie konfigurowały automatycznie portu 3306 na MySQL. Mamy dość problemów z cenieniem MySQL i MariaDB z dala od 3306.
Trunk
Uważaj na wtyczki Oracle, możesz dostać dużą karę: theregister.co.uk/2019/10/04/oracle_virtualbox_merula
Juha Untinen
To doskonała odpowiedź zasługuje na więcej entuzjastów!
Czerwiec Wenston,
82

Korzystanie ze starych mysql_native_passwordprac:

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;

Jest tak, ponieważ caching_sha2_passwordwprowadzono go w MySQL 8.0, ale wersja Node.js nie jest jeszcze zaimplementowana. Możesz zobaczyć to żądanie ściągnięcia i ten problem, aby uzyskać więcej informacji. Prawdopodobnie poprawka pojawi się wkrótce!

podnoszenie
źródło
Pracuj jak urok. Co za ulga!
kapelusz
jaka jest różnica między dodaniem @localhost a po prostu „rootem”
filemonczyk
Zapytanie działa. Ale nadal węzeł nie mógł połączyć się z serwerem MySQL. Dowolny pomysł? Oto błąd: {„kod”: „ER_ACCESS_DENIED_ERROR”, „errno”: 1045, „sqlMessage”: „Odmowa dostępu dla użytkownika„ root ”@„ localhost ”(przy użyciu hasła: TAK)”, „sqlState”: „28000” , „fatal”: true}
Sanjay Pradeep
26

Pełne kroki dla MySQL 8

Połącz się z MySQL

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

Zresetuj swoje hasło

(Zastąp your_new_passwordhasło, którego chcesz użyć)

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

Następnie spróbuj połączyć się za pomocą węzła

joshuakcockrell
źródło
@sky zobacz moją odpowiedź powyżej, aby poznać szczegóły.
Aidin
1
@Aidin Dzięki, to bardzo pomocne.
Sky
17

Chociaż zaakceptowana odpowiedź jest prawidłowa, wolałbym utworzyć nowego użytkownika, a następnie użyć go do uzyskania dostępu do bazy danych.

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';
Siddhant
źródło
2
Jeśli ktoś chce iść tą drogą, oto artykuł z wyjaśnieniem: digitalocean.com/community/tutorials/...
Devin
12

Jeśli napotkałeś ten błąd, ale nadal chciałeś używać MySQLwersji 8. Możesz to zrobić, informując MySQL Server, aby używał starszej wtyczki uwierzytelniającej podczas tworzenia bazy danych Docker.

Twój composeplik będzie wyglądał następująco:

# 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
Bogaty
źródło
Korzystam z tego command, ale wciąż pojawia się nieobsługiwany komunikat o błędzie uwierzytelnienia podczas używania mysqlw Node.js
Juha Untinen
Pełny stacktrace jest tutaj: pastebin.com/SzayQzdh i docker-compose.yml : pastebin.com/7pUrWYDs Sam błąd to:Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Juha Untinen
1
@JuhaUntinen upewnij się, że usunąłeś kontener Docker (ten utworzony przez docker-compose) i wolumin (~ / Database / ORM_Test), a następnie ponownie uruchom „docker-compose up”. W przeciwnym razie zmiany z „polecenia” nie zostaną zastosowane. Pomogło w moim przypadku.
Vitalii Ivanov
11

W Mysql Najnowszy kontener dokerów

ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';
MacielJr
źródło
9

Jeśli wiersz polecenia ALTER USER ... nie działa dla Ciebie ORAZ jeśli używasz systemu Windows 10, spróbuj wykonać następujące kroki:

1) Wpisz MySQL w pasku wyszukiwania systemu Windows

2) Otwórz Instalator Windows MySQL - Społeczność

3) Poszukaj „serwera MySQL” i kliknij przycisk Konfiguruj ponownie krok 3

4) Klikaj „Dalej”, aż dojdziesz do fazy „Metoda uwierzytelnienia”

5) W fazie „Metoda uwierzytelnienia” zaznacz drugą opcję „Użyj starszej metody uwierzytelnienia” krok 5

6) Następnie postępuj zgodnie z instrukcjami podanymi przez instalatora Windows do końca

7) Po zakończeniu przejdź do „Usługi” z paska wyszukiwania Windows, kliknij „uruchom” MySql81.

Teraz spróbuj ponownie, połączenie między MySQL i Node.js powinno działać!

Campalo
źródło
4

W MySQL 8.0 caching_sha2_passwordjest domyślną wtyczką uwierzytelniającą zamiastmysql_native_password. ...

Większość odpowiedzi w tym pytaniu powoduje obniżenie poziomu mechanizmu uwierzytelniania z caching_sha2_passwordna mysql_native_password. Z punktu widzenia bezpieczeństwa jest to dość rozczarowujące.

Ten dokument obszernie omawia caching_sha2_passwordi oczywiście, dlaczego NIE powinien być pierwszym wyborem obniżenia metody uwierzytelniania.

W związku z tym uważam, że odpowiedź Aidina powinna być odpowiedzią zaakceptowaną. Zamiast obniżyć klasę metody uwierzytelniania, użyj łącznika pasującego do wersji serwera.

Lester
źródło
3

Oryginalną dokumentację można znaleźć tutaj: 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);
  });
Shivang Patel
źródło
Wygląda to bardziej skomplikowane, ale myślę, że powinniśmy postępować zgodnie z oficjalnym przewodnikiem! b
Juneyoung
3

Mam MYSQL na serwerze i aplikację nodejs na innym serwerze

Wykonaj następujące zapytanie w MYSQL Workbench

ZMIEŃ UŻYTKOWNIKA „root” @ „%” IDENTYFIKOWANY ZA POMOCĄ mysql_native_password BY „hasło”

Iomar
źródło
2

W przypadku istniejących mysql instaluje się w mysql Windows 10,

(1) uruchom instalator,

(2), a następnie kliknij „Zmień konfigurację” w QuickAction (po lewej stronie MySQL Server)

(3) kliknij przycisk Dalej, aby przejść przez kolejne 2 ekrany do przybycia

(4) w „Metoda uwierzytelniania” wybierz „Użyj starszej metody uwierzytelnienia (zachowaj zgodność z MySQL 5.x”)

(5) Klikaj, aż instalacja się zakończy

Charles Goodwin
źródło
2

W MySQL 8+ nowe domyślne uwierzytelnianie jest caching_sha2_passwordzamiast mysql_native_password. Nowa i bardziej bezpieczna metoda uwierzytelniania nie jest jeszcze obsługiwana przez mysqlpakiet macierzysty , ale należy rozważyć użycie pakietu @mysql/xdevapi, który jest oficjalnie obsługiwany i obsługiwany przez Oracle.

Aby zainstalować nowy pakiet, uruchom:

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

Aby połączyć się z bazą danych i WSTAWIĆ niektóre WARTOŚCI:

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

Oficjalna dokumentacja pakietu znajduje się tutaj: https://dev.mysql.com/doc/dev/connector-nodejs/8.0/

Starszy Druid
źródło
2

Jeśli używasz dokera, zadziałało to dla mnie!

w docker-compose.ymldodaj następujące wiersze:

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

potem downpojemnik i upjeszcze raz.

Lew
źródło
1

Oprócz powyższych odpowiedzi; Po wykonaniu poniższej komendy

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

Jeśli pojawi się błąd jako:

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

Następnie spróbuj w cmd jako admin; ustaw ścieżkę do folderu bin serwera MySQL w cmd

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

a następnie uruchom polecenie:

mysql_upgrade --force -uroot -p

Powinno to zaktualizować serwer i tabele systemowe.

Następnie powinieneś być w stanie pomyślnie uruchomić poniższe polecenia w zapytaniu w środowisku roboczym:

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

pamiętaj, aby wykonać następujące polecenie:

flush privileges;

Po wykonaniu wszystkich tych kroków powinno być możliwe nawiązanie połączenia z bazą danych MySQL. Mam nadzieję że to pomoże...

Madhawa Jayagoda
źródło
0

Wystarczy uruchomić instalator serwera MySQL i ponownie skonfigurować My SQL Server ... To zadziałało dla mnie.

Alexander Burias
źródło
0

Sprawdź uprawnienia i nazwę użytkownika / hasło dla użytkownika MySQL.

Do wychwytywania błędów zawsze przydatna jest _delegateErrormetoda przesłonięta . W twoim przypadku musi to wyglądać następująco:

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

Ta konstrukcja pomoże ci prześledzić krytyczne błędy.

B. Bohdan
źródło
0

Właśnie to rozgryzłem po wypróbowaniu wielu rzeczy. To, co w końcu mi zrobiło, to dodanie require('dotenv').config()do mojego .sequelizercpliku. Najwyraźniej sequelize-cli nie czyta zmiennych env.

gbland777
źródło
0

Obniżenie klasy może nie być dobrym rozwiązaniem, ponieważ:

  1. Ulepszony z jakiegoś powodu (w celu zapewnienia lepszego uwierzytelnienia).
  2. Możesz nie mieć wystarczających uprawnień, aby wprowadzić takie zmiany.

Możesz użyć mysql2pakietu zamiast mysql. Jego API jest w większości kompatybilne z mysqljs. Obiecuje także wsparcie.

Używaj go jak: const mysql = require('mysql2/promise')

Możesz przeczytać więcej o mysql2tutaj: https://www.npmjs.com/package/mysql2

Mam nadzieję, że to pomoże. :)

Salim Shamim
źródło
0

Możesz pominąć ORM, konstruktory itp. I uprościć zarządzanie DB / SQL za pomocą sqleri sqler-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');
});
brzydki
źródło
-1

Mam ten sam problem z MySQL i rozwiązuję go za pomocą XAMPP do łączenia się z MySQL i zatrzymywania usług w systemie Windows dla MySQL (panel sterowania - Narzędzia administracyjne - Usługi) oraz w folderze db.js (odpowiedzialnym za bazę danych) I pozostaw hasło puste (tutaj możesz zobaczyć :)

const mysql = require('mysql');
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: ''
});
Mohammad Jouza
źródło
proszę nie dodawać problemu, który napotykasz, jako odpowiedzi na napotkany problem
Aloy A Sen