MySQL 8.0 - Le client ne prend pas en charge le protocole d'authentification demandé par le serveur; envisager de mettre à niveau le client MySQL

274

Je ne peux pas établir une simple connexion au serveur pour une raison quelconque. J'installe la dernière base de données MySQL Community 8.0 avec Node.JS avec les paramètres par défaut.

Ceci est mon code 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!");
    });

Voici l'erreur trouvée dans l'invite de commande:

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)

J'ai lu des choses telles que: https://dev.mysql.com/doc/refman/5.5/en/old-client.html https://github.com/mysqljs/mysql/issues/1507

Mais je ne sais toujours pas comment résoudre mon problème. Toute aide serait appréciée: D

Porc
la source
2
Tous les utilisateurs de VS Code qui utilisent l'extension SQLTools doivent se référer à ce message au cas où ils auraient des problèmes avec cela, surtout si vous venez de mettre à niveau une instance mysql sur votre ordinateur de développement
OzzyTheGiant

Réponses:

680

Exécutez la requête suivante dans MYSQL Workbench

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

Où en roottant qu'utilisateur localhostcomme URL et passwordcomme mot de passe

Exécutez ensuite cette requête pour actualiser les privilèges:

flush privileges;

Essayez de vous connecter à l'aide d'un nœud après cela.

Si cela ne fonctionne pas, essayez-le sans @'localhost'pièce.

Pras
la source
47
Cela a fonctionné pour moi. N'oubliez pas flush privileges;après.
Ali Hesari
12
Cela a fonctionné pour moi sans @localhost (je suppose que cela pourrait être parce que ce n'était pas pour l'utilisateur root)
NicolasZ
10
remplacez 'mot de passe' par votre mot de passe root si vous le connaissez
Vedha Peri
11
Cela fonctionne ... mais pourquoi cela ne fonctionnait pas avant et pourquoi cela fonctionnait après cette requête est toujours une question.
saksham
9
Salut @GuilhermeMatuella C'est parce que caching_sha2_passwordest introduit dans MySQL 8.0, mais la version Node.js n'est pas encore implémentée.
Daksh Gargas
108

Voyons d'abord clairement ce qui se passe.

MySQL 8 prend en charge les méthodes d'authentification enfichables. Par défaut, l'un d'eux nommé caching_sha2_passwordest utilisé plutôt que notre bon vieux mysql_native_password( source ). Il devrait être évident que l'utilisation d'un algorithme de chiffrement avec plusieurs poignées de main est plus sécurisée que la simple transmission de mots de passe qui existe depuis 24 ans !

Maintenant, le problème est mysqljsdans Node (le package avec lequel vous installez npm i mysqlet l'utilisez dans votre code Node) ne prend pas encore en charge cette nouvelle méthode d'authentification par défaut de MySQL 8. Le problème est ici: https://github.com/mysqljs/mysql/issues/1507 et est toujours ouvert, après 3 ans, à partir de juillet 2019.

(MISE À JOUR juin 2019: Il y a maintenant un nouveau PR dans mysqljs pour résoudre ce problème! ) (MISE À JOUR février 2020: Apparemment, il est prévu de venir dans la version 3 de mysqljs . )

Vos options

Option 1) Rétrograder "MySQL" pour s'authentifier en utilisant le bon vieux "native_password"

C'est ce que tout le monde suggère ici (par exemple, la première réponse ci-dessus ). Vous venez de lancer mysqlet d'exécuter une requête disant que tout rootva bien en utilisant l'ancienne native_passwordméthode d'authentification:

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

La bonne chose est que la vie va être simple et vous pouvez toujours utiliser de bons vieux outils comme Sequel Pro sans aucun problème . Mais le problème est que vous ne profitez pas d'un matériel plus sûr (et cool, lire ci-dessous) à votre disposition.

Option 2) Remplacer le package "Node" par MySQL Connecter X DevAPI

MySQL X DevAPI pour Node est un remplacement du package Mysqljs de Node , fourni par les gars officiels de http://dev.mysql.com .

Cela fonctionne comme un charme prenant en charge l' caching_sha2_passwordauthentification. (Assurez-vous simplement d'utiliser le port 33060pour les communications du protocole X. )

La mauvaise chose est que vous avez quitté notre ancien mysqlpackage auquel tout le monde est tellement habitué et sur lequel il s'appuie.

La bonne chose est que votre application est plus sécurisée maintenant et vous pouvez profiter d'une tonne de nouvelles choses que nos bons vieux amis n'ont pas fournies! Consultez simplement le tutoriel de X DevAPI et vous verrez qu'il a une tonne de nouvelles fonctionnalités sexy qui peuvent être utiles. Il vous suffit de payer le prix d'une courbe d'apprentissage, qui est attendue avec toute mise à niveau technologique. :)

PS. Malheureusement, ce package XDevAPI n'a pas encore de définition de types (compréhensible par TypeScript), donc si vous êtes sur typecript , vous aurez des problèmes. J'ai essayé de générer des .d.ts en utilisant dts-genet dtsmake, mais sans succès. Alors garde ça en tête.

À votre santé!

Aide à
la source
3
Merci d'avoir posté une réponse détaillée à une question vieille d'un an. :]
Daksh Gargas
3
agréable, une réponse qui explique réellement mysql_native_password au lieu de simplement vous dire de le faire
wizloc
1
Oui, une bonne explication pour une fois. Bien pour toi Aidin. Comment je souhaite que la connexion des applications n'ait pas configuré automatiquement le port 3306 sur MySQL. Nous avons assez de mal à séparer MySQL et MariaDB de 3306.
Trunk
Faites attention aux plugins Oracle, vous pourriez obtenir une grosse pénalité: theregister.co.uk/2019/10/04/oracle_virtualbox_merula
Juha Untinen
C'est une excellente réponse qui mérite plus de votes positifs!
June Wenston
82

En utilisant les anciennes mysql_native_passwordœuvres:

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;

En effet, caching_sha2_passwordest introduit dans MySQL 8.0, mais la version Node.js n'est pas encore implémentée. Vous pouvez voir cette demande d'extraction et ce problème pour plus d'informations. Une solution viendra probablement bientôt!

upupming
la source
Travaillez comme un charme. Quel soulagement!
chapeau
quelle est la différence entre l'ajout de @localhost et simplement «root»
filemonczyk
La requête fonctionne. Mais le nœud n'a toujours pas pu se connecter au serveur MySQL. Une idée? Voici l'erreur, {"code": "ER_ACCESS_DENIED_ERROR", "errno": 1045, "sqlMessage": "Accès refusé pour l'utilisateur 'root' @ 'localhost' (en utilisant le mot de passe: YES)", "sqlState": "28000" , "fatal": true}
Sanjay Pradeep
26

Étapes complètes pour MySQL 8

Connectez-vous à MySQL

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

réinitialisez votre mot de passe

(Remplacez your_new_passwordpar le mot de passe que vous souhaitez utiliser)

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

Essayez ensuite de vous connecter à l'aide d'un nœud

joshuakcockrell
la source
@sky voir ma réponse ci-dessus pour les détails.
Aidin
1
@Aidin Merci, c'est très utile.
Sky
17

Bien que la réponse acceptée soit correcte, je préfère créer un nouvel utilisateur, puis utiliser cet utilisateur pour accéder à la base de données.

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
la source
2
Si quelqu'un veut suivre cette voie, voici un article avec quelques explications: digitalocean.com/community/tutorials/…
Devin
12

Si vous avez rencontré cette erreur mais que vous vouliez toujours utiliser la MySQLversion 8. Vous pouvez y parvenir en disant à MySQL Server d'utiliser le plug-in d'authentification hérité lorsque vous créez la base de données à l'aide deDocker .

Ainsi, votre composefichier ressemblera à ceci:

# 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
Riches
la source
J'utilise ceci command, mais mysql
j'obtiens
La stacktrace complète est ici: pastebin.com/SzayQzdh et le docker-compose.yml : pastebin.com/7pUrWYDs L'erreur elle-même est:Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
Juha Untinen
1
@JuhaUntinen assurez-vous d'avoir supprimé un conteneur Docker (celui créé par docker-compose) et un volume (~ / Database / ORM_Test), puis exécutez à nouveau 'docker-compose up'. Sinon, les modifications de «commande» ne seront pas appliquées. Cela a aidé dans mon cas.
Vitalii Ivanov
11

Dans Mysql Dernier conteneur docker

ALTER USER root IDENTIFIED WITH mysql_native_password BY 'password';
MacielJr
la source
9

Si la ligne de commande ALTER USER ... ne fonctionne pas pour vous ET si vous utilisez Windows 10, essayez de suivre ces étapes:

1) Tapez MySQL dans la barre de recherche Windows

2) Ouvrez MySQL Windows Installer - Community

3) Recherchez "serveur MySQL" et cliquez sur Reconfigurer étape 3

4) Cliquez sur "Suivant" jusqu'à atteindre la phase "Méthode d'authentification"

5) Dans la phase "Méthode d'authentification", cochez la deuxième option "Utiliser la méthode d'authentification héritée" étape 5

6) Suivez ensuite les étapes données par le programme d'installation de Windows jusqu'à la fin

7) Quand c'est fait, allez dans "Services" dans la barre de recherche Windows, cliquez sur "démarrer" MySql81 ".

Maintenant, essayez à nouveau, la connexion entre MySQL et Node.js devrait fonctionner!

Campalo
la source
4

Dans MySQL 8.0, caching_sha2_passwordest le plugin d'authentification par défaut plutôt quemysql_native_password. ...

La plupart des réponses à cette question entraînent une rétrogradation du mécanisme d'authentification de caching_sha2_passwordà mysql_native_password. Du point de vue de la sécurité, c'est assez décevant.

Ce document explique en détail caching_sha2_passwordet bien sûr pourquoi il ne devrait pas être un premier choix pour rétrograder la méthode d'authentification.

Sur ce, je crois que la réponse d'Aidin devrait être la réponse acceptée. Au lieu de rétrograder la méthode d'authentification, utilisez plutôt un connecteur qui correspond à la version du serveur.

Lester
la source
3

La documentation originale que vous pouvez trouver ici: 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
la source
Cela semble plus compliqué, mais je pense que nous devrions suivre le guide officiel! b
Juneyoung Oh
3

J'ai MYSQL sur le serveur et l'application nodejs sur un autre serveur

Exécutez la requête suivante dans MYSQL Workbench

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

iomar
la source
2

Avec MySQL 8+, la nouvelle authentification par défaut est caching_sha2_passwordau lieu de mysql_native_password. La nouvelle méthode d'authentification plus sécurisée n'est pas encore prise en charge par le mysqlpackage natif , mais vous devriez envisager d'utiliser le package@mysql/xdevapi place, qui est officiellement pris en charge et maintenu par Oracle.

Pour installer le nouveau package, exécutez:

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

Pour vous connecter à la base de données et INSÉRER des VALEURS:

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

La documentation officielle du package peut être trouvée ici: https://dev.mysql.com/doc/dev/connector-nodejs/8.0/

Ancien druide
la source
2

Si vous utilisez Docker, cela a fonctionné pour moi!

dans l' docker-compose.ymlajout des lignes suivantes:

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

après cela, downle conteneur et upencore.

Leo
la source
2

Pour les installations mysql 8.0 existantes sur Windows 10 mysql,

  1. lancer l'installateur,

  2. cliquez sur "Reconfigurer" sous QuickAction (à gauche de MySQL Server), puis

  3. cliquez sur suivant pour avancer dans les 2 écrans suivants jusqu'à l'arrivée

  4. dans "Méthode d'authentification", sélectionnez "Utiliser la méthode d'authentification héritée (conserver la compatibilité MySQL 5.x"

  5. Continuez à cliquer jusqu'à ce que l'installation soit terminée

Charles Goodwin
la source
1

En plus des réponses ci-dessus; Après avoir exécuté la commande ci-dessous

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

Si vous obtenez une erreur comme:

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

Essayez ensuite dans le cmd en tant qu'administrateur; définir le chemin d'accès au dossier bin du serveur MySQL dans le cmd

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

puis exécutez la commande:

mysql_upgrade --force -uroot -p

Cela devrait mettre à jour le serveur et les tables système.

Ensuite, vous devriez être en mesure d'exécuter avec succès les commandes ci-dessous dans une requête dans le Workbench:

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

n'oubliez pas d'exécuter la commande suivante:

flush privileges;

Après toutes ces étapes, vous devriez pouvoir vous connecter avec succès à votre base de données MySQL. J'espère que cela t'aides...

Madhawa Jayagoda
la source
0

Il suffit d'exécuter MySQL Server Installer et de reconfigurer My SQL Server ... Cela a fonctionné pour moi.

Alexander Burias
la source
0

Vérifiez les privilèges et le nom d'utilisateur / mot de passe de votre utilisateur MySQL.

Pour détecter les erreurs, il est toujours utile d'utiliser la _delegateErrorméthode redéfinie . Dans votre cas, cela doit ressembler à:

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

Cette construction vous aidera à retracer les erreurs fatales.

Bohdan
la source
0

Je viens de comprendre cela après avoir essayé de nombreuses choses. Ce qui m'a finalement permis d'ajouter require('dotenv').config()à mon .sequelizercdossier. Apparemment, sequelize-cli ne lit pas les variables env.

gbland777
la source
0

Vous pouvez ignorer l'ORM, les générateurs, etc. et simplifier votre gestion DB / SQL à l'aide de sqleret 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');
});
ugate
la source
0

Le déclassement n'est peut-être pas une bonne option car:

  1. Son mis à jour pour une raison (pour fournir une meilleure authentification).
  2. Vous n'avez peut-être pas suffisamment d'autorisations pour effectuer de telles modifications.

Vous pouvez utiliser le mysql2package à la place demysql . Son API est principalement compatible avec mysqljs. En outre, il a promis un soutien.

Utilisez-le comme: const mysql = require('mysql2/promise')

Vous pouvez en savoir plus sur mysql2ici: https://www.npmjs.com/package/mysql2

J'espère que ça aide. :)

Salim Shamim
la source
-1

J'ai le même problème avec MySQL et je le résout en utilisant XAMPP pour me connecter avec MySQL et arrêter les services dans Windows pour MySQL (panneau de configuration - Outils d'administration - Services), et dans le dossier db.js (responsable de la base de données) I videz le mot de passe (ici vous pouvez voir :)

const mysql = require('mysql');
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: ''
});
Mohammad Jouza
la source
veuillez ne pas ajouter un problème auquel vous êtes confronté en tant que réponse au problème rencontré
Aloy A Sen