Mysql - 2054 Error (auth plugin匹配问题)

1. 错误描述

通过PHP7.3版本, 在连接8.0版本的MariaDB过程中,出现下错误:

SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

2. 问题原因

Mysql的默认认证插件的支持在8.0版本的MariaDB有所改变,同时PHP版本的auth未得以插件认证支持。

3. ALTER USER语法

首先,我们查看alter user语法(help alter user):

ALTER USER [IF EXISTS]
    user [auth_option] [, user [auth_option]] ...
    [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
    [WITH resource_option [resource_option] ...]
    [password_option | lock_option] ...
...
// 其 auth_plugin部分就是认证插件部分
auth_option: {
    IDENTIFIED BY 'auth_string'
  | IDENTIFIED WITH auth_plugin
  | IDENTIFIED WITH auth_plugin BY 'auth_string'
  | IDENTIFIED WITH auth_plugin AS 'hash_string'
}

相关Mysql官方文档说明: https://dev.mysql.com/doc/refman/8.0/en/alter-user.html

auth_plugin命名身份验证插件。插件名称可以是带引号的字符串文字或不带引号的名称。插件名称存储在系统表的plugin列中 mysql.user。

对于auth_option未指定身份验证插件的语法,默认插件由default_authentication_plugin 系统变量的值指示 。

4. 查看系统变量 - default_authentication_plugin

mysql> show variables like 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | caching_sha2_password |
+-------------------------------+-----------------------+
1 row in set (0.18 sec)

5. 查看用户认证plugin插件 - mysql.user表

可以通过查看mysql.user表的相关账户认证插件设定相关(root用户为我修复后的):

mysql> SELECT user,host,plugin,authentication_string FROM mysql.user;
+------------------+-----------+-----------------------+------------------------------------------------------------------------+
| user             | host      | plugin                | authentication_string                                                  |
+------------------+-----------+-----------------------+------------------------------------------------------------------------+
| root             | %         | sha256_password       | $5$fWD:17IF<2PCGz&br+HQ$PPnWLZOAphhFcZmpLsQBLGErPgm6dJ.XxjH7WZcat78    |
| mysql.infoschema | localhost | caching_sha2_password | $A$005$AHISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session    | localhost | caching_sha2_password | $A$005$AHISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys        | localhost | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root             | localhost | mysql_native_password | *9CABFAY8B170B87B9D04B816E54FE0700D2115A4                              |
+------------------+-----------+-----------------------+------------------------------------------------------------------------+

相关Mysql的插件参考:https://dev.mysql.com/doc/refman/8.0/en/authentication-plugins.html

6. Fix方式

确保连接的Mysql客户端库支持服务端账户设定的插件,

比如PHP7.3支持的Mysql认证插件清单,通过phpinfo()函数可查看到:

mysqlnd,debug_trace,auth_plugin_mysql_native_password,auth_plugin_mysql_clear_password,auth_plugin_sha256_password

我们可以发现,没有支持Mysql8.0中的默认的caching_sha2_password插件,因此出现了文章开头的错误。

可以通过将服务端的受限制账户连接插件修改为sha256_password,这样PHP客户端方面的Mysql连接认证插件就得以支持:

// 更改Mysql服务端受限制账户中的认证插件机制为`sha256_password`或者是`mysql_native_password`
ALTER USER 'root'@'%' IDENTIFIED WITH sha256_password BY 'password'; 

另外,注意后续相关新账户create user时候,也需要加入对客户端with auth_plugin的支持!

7. 相关参考