Node.js应用连接Amazon RDS MySQL实例时遇Access Denied错误求助
Node.js + mysql2/promise 连接Amazon RDS MySQL实例遇Access Denied错误排查
错误信息
Error: Access denied for user 'db_user'@'my.ip.address' (using password: YES)
连接代码
const mysql = require('mysql2/promise'); const connection = await mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT });
环境变量
DB_HOST=mydatabase.example.com DB_PORT=3306 DB_USER=db_user DB_PASSWORD=hidden_password DB_NAME=my_database
已做配置与尝试
- 安全组已配置允许本地IP地址访问3306端口
- 验证过凭证和用户权限
- 通过Workbench连接RDS实例时执行以下命令,但问题依旧:
GRANT ALL PRIVILEGES ON admin.* TO 'db_user'@'my.ip.address'; FLUSH PRIVILEGES;
Express路由示例
const express = require('express'); const dotenv = require('dotenv'); const path = require('path'); const mysql = require('mysql2/promise'); const router = express.Router(); const bcrypt = require('bcryptjs'); const authenticateToken = require('./middleware/authenticateToken.cjs'); const env = process.env.NODE_ENV || 'development'; dotenv.config({ path: path.resolve(__dirname, '../.env') }); var pool = mysql.createPool({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, port: process.env.DB_PORT }); // Handling connection establishment pool.getConnection((err, connection) => { if (err) { console.error('Database connection error:', err); return; } console.log('Database connection established'); connection.release(); // Release the connection back to the pool }); router.get('/get-locations', authenticateToken, async (req, res) => { try { const [results] = await pool.query('SELECT * FROM location'); res.status(200).json(results); } catch (error) { console.error('Error fetching locations:', error); res.status(500).send('Error fetching locations'); } });
排查建议
1. 修正用户权限范围
你的环境变量指定的数据库是my_database,但之前执行的授权命令是针对admin.*,权限范围不匹配。执行以下命令重新授权:
GRANT ALL PRIVILEGES ON my_database.* TO 'db_user'@'my.ip.address'; FLUSH PRIVILEGES;
执行后可以通过Workbench查询权限是否生效:
SHOW GRANTS FOR 'db_user'@'my.ip.address';
2. 确认用户主机匹配
登录RDS的MySQL实例,执行以下命令查看用户的主机配置:
SELECT user, host FROM mysql.user WHERE user = 'db_user';
确保返回的host字段和错误信息中的my.ip.address完全一致,或者使用%允许该用户从任意IP连接(测试用,生产环境不建议):
GRANT ALL PRIVILEGES ON my_database.* TO 'db_user'@'%'; FLUSH PRIVILEGES;
3. 验证环境变量加载正确性
在代码中添加日志,确认环境变量是否正确读取:
console.log('DB配置:', process.env.DB_HOST, process.env.DB_USER, process.env.DB_NAME);
同时检查.env文件路径是否正确,dotenv.config中的路径是否指向实际的.env文件位置。
4. 检查密码有效性
- 直接在Workbench使用相同的
db_user、密码和你的IP地址连接,确认密码是否正确。 - 如果密码包含特殊字符(如
!@#$%^&*),确保.env文件中密码用双引号包裹,避免解析错误:DB_PASSWORD="hidden_password_with_special_chars"
5. 排查RDS附加限制
- 检查RDS实例是否启用了IAM数据库认证,如果启用,需要使用IAM角色生成临时凭证,而非固定密码连接。
- 确认RDS实例的VPC网络ACL是否允许3306端口的入站流量,部分场景下安全组允许但ACL会拦截。
内容的提问来源于stack exchange,提问作者webdad3
相关产品推荐
相关产品推荐

