MySQL的mysql_native_password 错误怎么解决

127 阅读3分钟

背景

image.png

最近开发一个Node项目,需要使用数据库。自然地就选择了MySQL和mysql.js npm包,于是在本机上安装了MySQL的最新版本。结果项目启动出现错误

mysql 9.0 macos Plugin 'mysql_native_password' is not loaded

什么是 mysql_native_password

mysql_native_password 是 MySQL 数据库中使用的两种不同的认证插件,它们用于在客户端和服务器之间建立连接时验证用户的身份。它使用传统的密码散列方法,将用户的密码以明文形式发送到服务器,然后服务器使用自己的密码散列进行比较。并且是 MySQL 5.7 及之前版本中默认的认证插件。

从 MySQL 8.0 开始引入,caching_sha2_password作为新的默认认证插件。它使用 SHA-256 哈希算法和随机数来增强安全性,不再以明文形式发送密码。且该插件支持密码缓存,以减少密码验证过程中的计算开销。

如何继续使用 mysql_native_password

很显然,mysql.js npm包还是使用老的mysql_native_password插件,目前也不支持caching_sha2_password,见这个issue

反正我只是本地运行的MySQL服务,就把用户改成mysql_native_password好了:

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

果不其然出错了,再查资料发现mysql_native_password在MySQL 9.0版本后已经默认移除了。。。 要继续使用,只能降低MySQL版本到8.x。

但是注意MySQL 8.4已默认不再加载mysql_native_password插件,需要手动启用。先修改配置文件如下,然后手动重启服务。

# Enable mysql_native_password plugin
[mysqld]
mysql_native_password=ON

更好的办法

很显然mysql_native_password用明文在网络上传入密码很不安全,容易被攻击。caching_sha2_password更安全,且性能更好,我们应该尽量使用caching_sha2_password。Node客户端要使用这个认证插件有两个办法:

使用MySQL Connecter X DevAPI

MySQL X DevAPI for Node是官方团队提供的mysql.js包的替代品。它支持新的caching_sha2_password认证插件,且可以使用许多旧包没有提供的新功能。

但需要注意:

  1. 它33060端口来进行X协议的通信
  2. 它的API同mysql.js有很大不同
  3. MySQL X DevAPI包目前还没有TypeScript的类型定义(type definition)。如果你在使用TypeScript,可能会遇到问题。

如果你是新工程,可以直接使用这个方案。但如果你是老工程升级,很明显这个方案改造工作量很大,如果你想找一个更简单的方案请继续往下看。

使用mysql2.js

mysql2.jsmysql.js的一个fork分之,它支持caching_sha2_password,且它的API同mysql.js完全保持一致,可以直接替换

npm un mysql && npm i mysql2

经过实测,项目可以正常启动了。

后记

经过一番研究,现在对MySQL的认证机制了解的更加清楚。但我最后还是使用的降级版本的方案,因为线上环境使用的也是8.4版本😂 还是尽量保证本地和线上环境一致吧。。。