如何使用Node.js通过IAM认证访问RDS MySQL数据库
Node.js无密码访问AWS RDS MySQL(IAM认证实现)
问题描述
当前使用Node.js的mysql包连接RDS MySQL的代码如下:
const mysql = require("mysql"); const environment = require("../core/environment/environment"); const connection = mysql.createPool({ host: environment.mysql.host, port: environment.mysql.port, user: environment.mysql.user, password: environment.mysql.password, // 是否有办法避免使用密码 connectionLimit: 10 }); connection.connect(function(err) { if (err) { console.error('Database connection failed: ' + err.stack); return; } console.log('Connected to database.'); }); connection.end();
核心问题是必须在环境文件中存储并暴露数据库密码,希望通过AWS IAM数据库认证实现无密码访问,但官方文档仅提供Python、.NET等平台示例,缺少Node.js的具体实现方案。
实现方案
1. 前置准备
- 确保RDS MySQL实例已开启IAM数据库认证
- 创建具备
rds-db:connect权限的IAM角色/用户,并关联到Node.js应用所在的AWS资源(EC2/ECS/Lambda等);本地测试需配置对应权限的IAM凭证 - 为目标MySQL用户启用IAM认证,执行SQL:
ALTER USER '你的数据库用户名'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
2. 依赖安装
推荐使用@aws-sdk/client-rds-signer(AWS SDK v3)和mysql2(对IAM认证支持更友好):
npm install @aws-sdk/client-rds-signer mysql2
3. 代码实现
通过AWS SDK生成临时认证令牌替代传统密码:
const { RDSClient, GenerateAuthenticationTokenCommand } = require("@aws-sdk/client-rds-signer"); const mysql = require("mysql2/promise"); const environment = require("../core/environment/environment"); // 初始化RDS签名客户端 const rdsSigner = new RDSClient({ region: "你的AWS区域" // 例如: us-east-1 }); // 生成IAM认证临时令牌 async function getAuthToken() { const params = { hostname: environment.mysql.host, port: environment.mysql.port, username: environment.mysql.user }; const command = new GenerateAuthenticationTokenCommand(params); const token = await rdsSigner.send(command); return token; } // 创建连接池并初始化 async function initDbPool() { try { const authToken = await getAuthToken(); const pool = mysql.createPool({ host: environment.mysql.host, port: environment.mysql.port, user: environment.mysql.user, password: authToken, // 用临时令牌作为密码 database: "你的数据库名称", connectionLimit: 10, ssl: { // 生产环境建议配置AWS官方RDS CA证书,此处为简化配置 rejectUnauthorized: false } }); // 测试连接有效性 const [testResult] = await pool.query("SELECT 1 AS connection_test"); console.log("数据库连接成功,测试结果:", testResult[0].connection_test); return pool; } catch (err) { console.error("数据库连接失败:", err.stack); throw err; } } // 初始化连接池 initDbPool();
4. 关键注意事项
- 临时令牌有效期为15分钟,需实现令牌自动刷新逻辑:可在每次获取连接时重新生成令牌,或定时重建连接池
- AWS凭证获取:AWS托管环境(EC2/ECS/Lambda)会自动从实例元数据/任务角色获取凭证;本地测试需通过环境变量
AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY配置权限 - SSL配置:生产环境建议下载并配置AWS官方RDS CA证书,将路径传入
ssl.ca参数,确保连接安全性
内容的提问来源于stack exchange,提问作者micronyks
相关产品推荐
相关产品推荐

