Django连接只读MySQL遇ERROR 1045权限拒绝问题求助
核心线索:仅使用旧版libmysql-6.1.dll的HeidiSQL能成功连接,说明问题出在认证协议不匹配——新MySQL客户端默认采用caching_sha2_password认证,而你的只读用户仅支持旧的mysql_native_password认证方式,或数据库端权限配置绑定了旧认证的连接特征。
具体修复步骤
1. 确认数据库用户的认证插件
使用有权限的账号登录数据库服务器,执行以下SQL查看目标用户的认证方式:
SELECT user, host, plugin FROM mysql.user WHERE user = 'db-foo-read';
若结果中plugin字段为mysql_native_password,则可确定是新客户端的认证协议不兼容;若为caching_sha2_password,则旧版dll做了特殊兼容,需调整客户端配置。
2. 强制客户端使用旧认证方式
针对Django配置
修改数据库配置,添加OPTIONS参数强制使用mysql_native_password并禁用SSL(若无需SSL):
'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'db-foo', 'USER': 'db-foo-read', 'PASSWORD': 'djlkwajldljwj1ldwa1', 'HOST': '125.67.891.26', 'PORT': '3306', 'OPTIONS': { 'ssl': False, 'auth_plugin': 'mysql_native_password', }, }
如果使用pymysql作为驱动,需在项目初始化文件(如__init__.py)中添加以下代码:
import pymysql pymysql.install_as_MySQLdb()
针对MySQL Workbench/Shell
- MySQL Workbench:在连接配置的「Advanced」选项中,将
authPlugin=mysql_native_password添加到「Other connection parameters」 - MySQL Shell:连接时追加
--auth=mysql_native_password参数,命令修改为:
"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysql.exe" --user="db-foo-read" --password="djlkwajldljwj1ldwa1" --ssl-mode=DISABLED --host="125.67.891.26" --port=3306 --protocol=tcp --auth=mysql_native_password
3. 调整数据库用户的认证插件(需管理员权限)
若客户端配置无效,且你拥有数据库管理员权限,可直接修改用户的认证插件为兼容模式:
ALTER USER 'db-foo-read'@'125.67.891.26' IDENTIFIED WITH mysql_native_password BY 'djlkwajldljwj1ldwa1'; FLUSH PRIVILEGES;
注意:若用户允许从任意IP连接,将125.67.891.26替换为%即可。
4. 排查IP白名单/防火墙规则
虽然HeidiSQL能连接,但仍需确认数据库端防火墙是否仅放行特定客户端的连接特征(可能性较低,但可排除)。
原因说明
libmysql-6.1.dll是MySQL 5.6版本的客户端库,默认仅支持mysql_native_password认证,不会尝试新的caching_sha2_password协议,因此能匹配数据库端的用户配置;而MySQL 8.0及以上版本的客户端库默认使用新认证方式,导致权限验证失败。
内容的提问来源于stack exchange,提问作者Samuel Grosser

