JavaScript: Error: ER_NOT_SUPPORTED_AUTH_MODE: (中略) consider upgrading MySQL clientがMySQL使用時に出た時の対応例

Database

MySQLへの接続がうまく認識されない

タイトルにエラー時に出力する様に自分で付けた”error connecting:”が入っていた為、その部分を削除。紛らわしいタイトルで失礼しました。(2021/11/28夜追記)

ProgateさんのNode.jsコースを参考にしながら、買い物リストアプリを自Macでも作成中、MySQLと接続させる所でどうも上手く動いてくれず、何度やっても、下記エラーが出る。

TypeError: /Users/~/myapp/views/index.ejs:24
    22|           
    23|         <ul class="table-body">
 >> 24|           <% items.forEach((item) => { %>
    25|             <li>
    26|               <span class="id-column">
    27|               <%= item.id %>                
Cannot read properties of undefined (reading 'forEach')
    at eval ("/Users/~/myapp/views/index.ejs":12:14)
    at index 
(以降略)

因みに当方はMac使用、MySQLのバージョンは8.0.27 for macos11.6 on x86_64。

エラーメッセージの中の印”>>”が付いている所とこの前後を見ても、コード自体に問題は無さそう。

この行のコードで外から来ているデータは”items”の中身であり、この”items”の中身はデータベースから”SELECT * FROM items”文で得たデータ。

そう考えると、何となくitems内に上手くデータが取り込めていない、データベースとアプリが上手く接続できていない気がする。

エラーを表示させる

と言う事でデータベースの接続を確認する方法を探していた時に見つけたのがプロゲートの記事Node.jsアプリケーションとMySQLを接続しよう!

こちらを参考にさせて戴き、まずはMySQLへの接続ができていない時にエラーを表示させるコードを追記。

// MySQLへの接続ができていない時にエラーを表示させるコード
connection.connect((err) => {
  if (err) {
    console.log('error connecting: ' + err.stack);
    return;
  }
  console.log('success');
});

その上で改めてnode app.jsを実行した所、ブラウザの表示に変化はないが、ターミナルに下記エラーメッセージが出る様になった。

% node app.js
error connecting: Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client

いや〜、プロゲート様様(さまさま)、エラーメッセージ様様です。

このMySQLへの接続が出来ていない時にエラーを返すコードの大事さが分かる。

エラーメッセージで調べる

と言う事でこのエラーメッセージを元にグーグル先生に聞いてみた。
見た所、下記のstackoverflowの回答が一番詳しい様に思う。

MySQL 8.0 – Client does not support authentication protocol requested by server; consider upgrading MySQL client

今まではmysql_native_passwordで管理されていた所を、MySQL 8からcaching_sha2_passwordが導入されたので上手くNode.jsと繋がらなくなっている。
しかし、未だにこの変更には対応されていないとの事。

user, host, pluginを確認してみると、確かにcaching_sha2_passwordになっている。

mysql> SELECT user, host, plugin from mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| mysql.infoschema | localhost | caching_sha2_password |
| mysql.session    | localhost | caching_sha2_password |
| mysql.sys        | localhost | caching_sha2_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+
4 rows in set (0.00 sec)

エラーに対応する

今の所、解決法は下記3つ

  1. MySQLのダウングレード:これはお勧めでは無いとの事だが、確かに問題があるから古いバージョンで、と言うのは時流に取り残されるリスク大なので避けた方が良さそう。
  2. NodeのMySQLパッケージを提供されているMySQL X DevAPI for Nodeに置き換え:こちらも今一らしい。と言うのも、皆が使っていて定評のあるMySQL packageを完全に使わない事になるからだそう。
  3. mysql.jsのパッケージmysql2.jsのパッケージに置き換え:これが一番おすすめとの事。mysql2.jsはmysql.jsからフォーク(枝分かれ)したパッケージだそうで、簡単に修正できるようにされているとの事。

この中では3番が一番お勧めらしい。
実際mysqlとmysql2のページを見た所、2021/11/27現在で週毎のダウンロード数がmysqlが74万、mysql2が79万とmysql2の方が多用されている。

と言う事で、3で対応してみる。

まずはmysql2のインストール。

% npm install --save mysql2
added 14 packages, and audited 89 packages in 2s
found 0 vulnerabilities

インストール後のpackage.jsonは下記の通り。
mysqlとmysql2が両方あるのがわかる。

 % cat package.json 
{
  "name": "myapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "mysql": "^2.18.1",
    "mysql2": "^2.3.3"
  }
}

app.js のコードの変更は簡単。

app.jsの最初に書いている
const mysql = require(‘mysql’);
から
const mysql = require(‘mysql2’);
に変更するだけ。

エラーが解決する

この2つの手順だけで今まで何も返答がなかったnode app.jsコマンドにsuccessの返しが。
これは上手く行った兆し。

% node app.js              
success

ブラウザを見ると、ちゃんとデータベースの中身が表示されていた!

確かに3の解決方法が一番手っ取り早かった。
これはお勧め。

皆様の情報共有に感謝。

「Pythonではじめるアルゴリズム入門 伝統的なアルゴリズムで学ぶ定石と計算量」
以前紹介した事があるけれど、今はキャンペーンでKindle版が半額でお勧めなのでもう一度紹介するアルゴリズム本。
チャートと図で理解させてくれ、その理解を念頭にコードを読み解けば理解できる本であり、Pythonのアルゴリズムの本の内で未だに数が少ないリフロー版なので使い勝手が良い。
中古本は過去のほんの短い期間だけ600円台のものがあったけれど、今は総じて値段は高めで2021/11/28時点で1,900円台+送料と対中古本でもほぼ半値なので私の様な入門者で興味ある方にはお勧め。

コメント

タイトルとURLをコピーしました