绝大多数情况是MySQL侧用户权限、host匹配或认证插件不兼容所致;需核对'user'@'host'是否精确匹配mysql.user表记录,确认认证插件为mysql_native_password而非auth_socket或caching_sha2_password,并确保DBDriver、hostname、DSN等CI4配置与MySQL实际设置一致。

CodeIgniter 4 连 MySQL 报 “Access denied for user” 错误,绝大多数情况不是 CI4 配置写错了,而是 MySQL 侧的用户权限、host 匹配或认证插件不兼容导致的。CI4 本身只负责把配置传给 PDO 或 MySQLi,真正拒绝连接的是 MySQL 服务端。
一、先确认报错里的 'user'@'host' 是什么
错误信息通常长这样:Access denied for user 'app'@'127.0.0.1' (using password: YES)
或Access denied for user 'root'@'localhost'
→ 重点看单引号里的 'user'@'host',这是 MySQL 实际比对的账号标识,必须和 mysql.user 表里的一模一样(包括大小写、空格、IP/域名写法)。
执行这条命令查真实记录:
SELECT User, Host, plugin FROM mysql.user WHERE User = 'app';
如果结果里没有 'app'@'127.0.0.1',但你代码里连的是 127.0.0.1,那就必然失败——哪怕 'app'@'%' 存在也不行。
二、检查 MySQL 用户是否支持当前连接方式
-
'localhost'和'127.0.0.1'完全不等价:-
localhost→ 默认走 Unix socket(不走 TCP),可能用auth_socket插件(Ubuntu/Debian 常见); -
127.0.0.1→ 强制走 TCP,必须有对应'user'@'127.0.0.1'记录,且 plugin 兼容。
-
-
CI4 默认用 PDO 或 MySQLi,两者都依赖密码认证,不支持
auth_socket。
如果查出来 plugin 是auth_socket,必须换:ALTER USER 'app'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
-
MySQL 8.0+ 默认 plugin 是
caching_sha2_password,老版 PHP 扩展(如某些旧 Docker 镜像里的php-mysql)可能不支持。
安全做法是统一切回mysql_native_password:ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; FLUSH PRIVILEGES;
三、验证数据库配置是否匹配 MySQL 实际设置
打开 app/Config/Database.php,检查 $default 数组:
-
'DBDriver'必须是'MySQLi'或'PDO'(大小写敏感); -
'hostname'要和你连接时用的 host 一致:- 本地开发用
localhost?确保 MySQL 有'user'@'localhost'; - 用
127.0.0.1?确保有'user'@'127.0.0.1'; - Docker 环境常见填
mysql(容器名),那就要建'user'@'%'或'user'@'app-network-subnet';
- 本地开发用
-
'username'和'password'必须和mysql.user表里完全一致(注意空密码是'',不是null); - 若用
'PDO',必须补全'DSN'字段,例如:'DSN' => 'mysql:host=localhost;dbname=your_db;charset=utf8mb4',
缺了 DSN,PDO 会退回到默认 host,可能连错实例或触发默认权限策略。
Full access to all Exchange 2010 EWS functions, should work with other EWS Open Source下载可完全访问 Exchange 2010 EWS,管理邮件、文件夹、附件、日历事件、联系人、任务及外出设置。
改完配置后,别忘了清缓存:
php spark cache:clear
四、排除网络与服务层拦截
即使账号对了,也可能卡在更底层:
-
检查 MySQL 是否监听外部地址:
ss -tlnp | grep :3306
正常应看到
*:3306或0.0.0.0:3306;若只有127.0.0.1:3306,远程或容器内访问必失败。 -
查
my.cnf(通常是/etc/mysql/my.cnf或/etc/my.cnf)中:bind-address = 127.0.0.1 # ← 改成 0.0.0.0 才允许外连 require_secure_transport = ON # ← 临时关掉,避免非 SSL 连接被静默拒绝
防火墙或云服务器安全组:确认 3306 端口入方向已放行。
不复杂但容易忽略

















