上下文:
我刚刚创建了一个 Node.JS 应用程序,并在 AWS Lambda 上使用无服务器框架部署了它。
问题:
我希望该应用程序能够访问我的(免费套餐)MongoDB Atlas 集群。为此,我使用 mongoose
。
设置:
我有一个具有管理员访问权限的 IAM 用户。此用户已在我的 MongoDB 集群上获得授权。
我正在使用 authMechanism=MONGODB-AWS
,因此使用该 IAM 用户的令牌和秘密。密码已正确“url编码”。
这是用于创建连接的一段代码:
const uri = "mongodb+srv://myIAMtoken:myIAMsecret@cluster0.tfws6.mongodb.net/DBNAME?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority"
mongoose.connect(uri, {useNewUrlParser: true, useUnifiedTopology: true })
当我在笔记本电脑上运行此代码时,连接已建立,我可以检索所需的数据。 但是,当我在 AWS Lambda(通过无服务器)上部署完全相同的代码时,我得到了这个响应:
message "Internal server error"
CloudWatch 上的跟踪如下所示:
{
"errorType": "Runtime.UnhandledPromiseRejection",
"errorMessage": "MongoError: bad auth : aws sts call has response 403",
"reason": {
"errorType": "MongoError",
"errorMessage": "bad auth : aws sts call has response 403",
"code": 8000,
"ok": 0,
"codeName": "AtlasError",
"name": "MongoError",
"stack": [
"MongoError: bad auth : aws sts call has response 403",
" at MessageStream.messageHandler (/var/task/node_modules/mongodb/lib/cmap/connection.js:268:20)",
" at MessageStream.emit (events.js:314:20)",
" at processIncomingData (/var/task/node_modules/mongodb/lib/cmap/message_stream.js:144:12)",
" at MessageStream._write (/var/task/node_modules/mongodb/lib/cmap/message_stream.js:42:5)",
" at doWrite (_stream_writable.js:403:12)",
" at writeOrBuffer (_stream_writable.js:387:5)",
" at MessageStream.Writable.write (_stream_writable.js:318:11)",
" at TLSSocket.ondata (_stream_readable.js:718:22)",
" at TLSSocket.emit (events.js:314:20)",
" at addChunk (_stream_readable.js:297:12)",
" at readableAddChunk (_stream_readable.js:272:9)",
" at TLSSocket.Readable.push (_stream_readable.js:213:10)",
" at TLSWrap.onStreamRead (internal/stream_base_commons.js:188:23)"
]
},
"promise": {},
"stack": [
"Runtime.UnhandledPromiseRejection: MongoError: bad auth : aws sts call has response 403",
" at process.<anonymous> (/var/runtime/index.js:35:15)",
" at process.emit (events.js:314:20)",
" at processPromiseRejections (internal/process/promises.js:209:33)",
" at processTicksAndRejections (internal/process/task_queues.js:98:32)"
]
}
我认为这是来自 AWS 的网络访问问题,所以我尝试获取 "http://google.com" ,没问题,我的节点应用程序可以访问该页面并提供响应。我的应用程序可以访问互联网,但无法访问我的 MongoDB 云实例。可以从任何 IP 地址访问我的 MongoDB 集群。
这已经达到了我的知识极限:-)
答案 0 :(得分:1)
如果您使用的是 iam 类型的 mongodb 用户,则连接字符串中不需要用户名 + 密码。
const uri = "mongodb+srv://cluster0.tfws6.mongodb.net/DBNAME?authSource=$external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority"
当您调用连接到 mongodb 集群的 lambda 时,它将使用的 iam 角色将是 lambda 的执行角色
"arn:aws:iam::ACCOUNT_ID:role/SLS_SERVICE_NAME-ENVIRONMENT-AWS_REGION-lambdaRole"
"arn:aws:iam::123456789012:role/awesome-service-dev-us-east-1-lambdaRole"
检查 sls 框架的默认 iam 部分: https://www.serverless.com/framework/docs/providers/aws/guide/iam/#the-default-iam-role