MySQL远程连接失败,显示“未知的认证方法”。

13

我正在尝试从本地计算机远程连接到在线的MySQL服务器,但是我遇到了以下错误:

Warning: PDO::__construct(): The server requested authentication 
method unknown to the client [mysql_old_password] in 
C:\xampp\htdocs\ticket\terminal\sync.php

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

我的本地MySQL服务器版本是5.5.27,libmysql-mysqlnd版本为5.0.10。远程MySQL服务器的版本是5.5.23,但mysqlnd版本未暴露。

我猜这可能是由于密码哈希不兼容所导致的问题,但我不知道如何解决它。以下是我连接代码的一部分:

$dsn = 'mysql:host=184.173.209.193;dbname=my_db_name';
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
); 

try {
    $online_dbh = new PDO($dsn, 'myusername', 'mypassword', $options);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Congratulations!";
} catch (PDOException $e) {
    echo $e->getMessage();
} 

如果您指出第12行会更有帮助。 - david strachan
这对我有用:https://dev59.com/InM_5IYBdhLWcg3whzrx#22794125 - abbas
通过使用相同的凭据创建一个新用户来解决问题。 - Moxet Khan
相关:MySQL PHP 不兼容性 - kenorb
8个回答

13

假设您正在使用 PHP 5.3+,您可能遇到以下之一的向后不兼容性更改

新的 mysqlnd 库需要使用 MySQL 4.1 的新 41 字节密码格式。继续使用旧的 16 字节密码会导致 mysql_connect() 和类似函数发出错误:“mysqlnd 无法使用旧身份验证方法连接到 MySQL 4.1+”。

如果是这种情况,请查看https://dev59.com/InM_5IYBdhLWcg3whzrx#1340538 了解有关更新密码的信息。


5
这可能会对遇到此问题的人有所帮助。以下是我在自己的情况下解决此问题的方法。 来自MySQL PHP API (PDO_MYSQL)网站

当运行PHP 7.1.16之前的版本或者PHP 7.2之前的版本时,请将MySQL 8服务器的默认密码插件设置为mysql_native_password,否则你会看到类似于The server requested authentication method unknown to the client [caching_sha2_password]的错误提示,即使没有使用caching_sha2_password。

这是因为MySQL 8默认使用caching_sha2_password插件,而旧版PHP(mysqlnd)不识别该插件。因此,在my.cnf中设置default_authentication_plugin=mysql_native_password来更改它。caching_sha2_password插件将在未来的PHP版本中得到支持。与此同时,mysql_xdevapi扩展支持它。


在 macOS 中,"my.cnf" 文件位于哪里? - Abdul-Elah JS
如果您是通过brew安装的,那么my.cnf文件位于/usr/local/etc/目录下。 - cjohansson
这个答案对我有用,但是我不得不重新创建用户和密码才能使它工作。 - cjohansson
在我的情况下,在编辑了配置文件之后,我还发送了以下命令:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; - Velaro

3

我克服了这个挑战。我发现我的远程MySQL数据库主机仍然使用旧的MySQL密码哈希,长度为16字节,而我的本地数据库服务器使用41字节的密码哈希。我使用以下查询来查找密码长度:

SELECT PASSWORD('mypass') 

我通过运行以下查询将本地数据库服务器密码散列更改为16字节:

SET GLOBAL old_passwords = 1;

然后我编辑了my.ini文件,并将old_password=1设置为确保服务器重新启动时不会恢复到新密码系统。但这并没有解决我的问题。

我发现处理身份验证的是PHP,因为我使用了PHPMySQLAPI,所以我降级到了PHP 5.2.8,然后成功地进行了远程连接。

希望这能帮助到某些人。


@ian,所以你只是告诉我们降级似乎不正确,而你认为是正确的? - Chibuzo
@Chibuzo 是的,对我来说降级通常不是正确的解决方案。我通过确保我的mysql客户端版本与服务器版本保持最新来修复了我的问题。然后设置old_password = 0并设置一个新的root密码。 - ian
@ian 如果服务器不是你的,而你运行的版本比服务器高怎么办?那就是我的情况。解决方案是什么? - Chibuzo
只是为了明确:您不必更改my.ini MySql服务器配置中的任何内容,也不必降级PHP版本。 只需在当前会话中发出“set old_passwords = 0”后重置感兴趣的帐户的密码即可。 一旦密码更新,PDO就可以连接,无论服务器上的@@old_passwords值如何。 - Gabriel

3
使用 alter user 'username'@'localhost' identified with mysql_native_password by 'password'; 命令可解决此问题。

2

我遇到了同样的问题,发现问题确实与PHP有关。

对我来说,解决方案很简单:改用mysqli而不是PDO。当使用Zend_Db时,只需更改1行即可:

$db = Zend_Db::factory('pdo_mysql',array('host' => MYSQL_HOST, 'username' => MYSQL_USER, 'password' => MYSQL_PASS, 'dbname' => MYSQL_SCHEMA));

变成

$db = Zend_Db::factory('mysqli',array('host' => MYSQL_HOST, 'username' => MYSQL_USER, 'password' => MYSQL_PASS, 'dbname' => MYSQL_SCHEMA));

但是如果你的应用程序没有使用Zend_Db抽象层(或任何其他抽象层),那么你可能会遇到麻烦。


1
我在共享主机服务 (bluehost.com) 上遇到了这个问题。我只是通过Bluehost提供的Web界面重置了故障的MySql用户密码。我重新使用了旧密码,在界面上重新输入并保存,一切都恢复正常了。

0
如果您正在使用 Bitbucket PipelinesMySQL 5.8+,您可以像这样将已知参数 --default-authentication-plugin=mysql_native_password 添加到您的服务中:

definitions:
  services:
    mysql:
      image: mysql:8.0
      environment:
        MYSQL_DATABASE: 'app'
        MYSQL_ROOT_PASSWORD: 'root'
        MYSQL_DEFAULT_AUTH: 'mysql_native_password'

-1

我在使用 Laravel 5.6 和默认的 MySQL 数据库(设置为 services:)时,在运行 Bitbucket Pipelines 时遇到了这个问题。

解决方案是使用较旧版本的 MySQL。

definitions:
  services:
    mysql:
     image: mysql:5.6

备注:这是 PHP 7.1 版本。


更改了一个文件 bitbucket-pipelines.yml。 - Yevgeniy Afanasyev
我找到了一个解决方案并分享了出来。如果你知道更好的方法,请添加另一个答案。 - Yevgeniy Afanasyev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接