背景
最近开发一个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认证插件,且可以使用许多旧包没有提供的新功能。
但需要注意:
- 它33060端口来进行X协议的通信
- 它的API同
mysql.js
有很大不同 - MySQL X DevAPI包目前还没有TypeScript的类型定义(type definition)。如果你在使用TypeScript,可能会遇到问题。
如果你是新工程,可以直接使用这个方案。但如果你是老工程升级,很明显这个方案改造工作量很大,如果你想找一个更简单的方案请继续往下看。
使用mysql2.js
mysql2.js
是mysql.js
的一个fork分之,它支持caching_sha2_password,且它的API同mysql.js
完全保持一致,可以直接替换
npm un mysql && npm i mysql2
经过实测,项目可以正常启动了。
后记
经过一番研究,现在对MySQL的认证机制了解的更加清楚。但我最后还是使用的降级版本的方案,因为线上环境使用的也是8.4版本😂 还是尽量保证本地和线上环境一致吧。。。