Node.js 为什么可以';我的AWS Lambda节点JS应用程序是否可以访问我的MongoDB Atlas群集?

Node.js 为什么可以';我的AWS Lambda节点JS应用程序是否可以访问我的MongoDB Atlas群集?,node.js,mongodb,mongoose,aws-lambda,mongodb-atlas,Node.js,Mongodb,Mongoose,Aws Lambda,Mongodb Atlas,上下文: 我刚刚创建了一个Node.JS应用程序,并在AWS Lambda上使用无服务器框架进行了部署 问题: 我希望该应用程序能够访问我的(免费层)MongoDB Atlas集群。为此,我使用了mongoose 设置: 我有一个具有管理员访问权限的IAM用户。此用户已在我的MongoDB群集上获得授权。 我使用的是authMechanism=MONGODB-AWS,因此使用的是IAM用户的令牌和密码。密码已正确“url编码” 这是用于创建连接的一段代码: const uri = "m

上下文:

我刚刚创建了一个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上部署完全相同的代码时(通过Serverless),我得到以下响应:

    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)"
]
}
{
“errorType”:“Runtime.UnhandledPromiserExtraction”,
“errorMessage”:“MongoError:bad auth:aws sts调用有响应403”,
“理由”:{
“errorType”:“MongoError”,
“errorMessage”:“错误身份验证:aws sts调用有响应403”,
“代码”:8000,
“ok”:0,
“代号”:“AtlasError”,
“名称”:“MongoError”,
“堆栈”:[
“MongoError:bad auth:aws sts调用有响应403”,
“在MessageStream.messageHandler(/var/task/node_modules/mongodb/lib/cmap/connection.js:268:20)”中,
“在MessageStream.emit(events.js:314:20)”上,
“在processIncomingData(/var/task/node_modules/mongodb/lib/cmap/message_stream.js:144:12)”中,
“在MessageStream._write(/var/task/node_modules/mongodb/lib/cmap/message_stream.js:42:5)”,
“在doWrite(_stream_writable.js:403:12)”,
“在writeOrBuffer(_stream_writeable.js:387:5)”,
“在MessageStream.writeable.write(_stream_writeable.js:318:11)”中,
“在TLSSocket.ondata(_stream_readable.js:718:22)”,
“在TLSSocket.emit(events.js:314:20)”中,
“在addChunk(_stream_readable.js:297:12)”中,
“在readableAddChunk(_stream_readable.js:272:9)”中,
“在TLSSocket.Readable.push(_stream_Readable.js:213:10)”中,
“在TLSWrap.onStreamRead(内部/stream_base_commons.js:188:23)”
]
},
“承诺”:{},
“堆栈”:[
“Runtime.UnhandledPromiserExtraction:MongoError:bad auth:aws sts调用有响应403”,
“在进程中(/var/runtime/index.js:35:15)”,
“在process.emit(events.js:314:20)”中,
“在processPromiseRejections(internal/process/promises.js:209:33)”中,
“在处理和拒绝时(内部/process/task_queues.js:98:32)”
]
}
我认为这是AWS的网络访问问题,所以我尝试获取“http://google.com“,没问题,我的节点应用程序可以访问该页面并提供响应。我的应用可以访问internet,但无法访问我的MongoDB云实例。我的MongoDB集群可以从任何IP地址访问


这已达到我所知的极限:-)

如果您使用的是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"
检查sls框架的默认iam部分:

好的,非常感谢,这无疑是朝着正确方向迈出的一步。如果您能告诉我如何允许这个“角色”访问atlas上的mongodb集群,我将不胜感激?我在mongodb上注册并允许了一个“IAM”用户,该用户在连接url字符串中使用了“令牌”和“机密”。但是我不知道如何继续默认使用的这个角色,它不是我可以在mongoin mongodb atlas上允许的用户,它可以导航到您的项目,选择您的集群,转到左侧边栏上的数据库访问,并在那里创建一个IAM类型的用户,具有读取或读写数据库的权限。该用户的iam rola arn应为上述内容。“arn:aws:iam::ACCOUNT\u ID:role/SLS\u SERVICE\u NAME-ENVIRONMENT-aws\u REGION-lambdaRole”再次感谢@纳斯辛本让我知道最后你是否能解决你的问题,我的回答是否足够有用。顺便说一句,用户创建的用户名+密码类型与iam类型的工作方式相同,区别在于您必须将URL编码的用户名+密码添加到连接字符串中,并且authSource将是admin,而不是$external。如果在终端中运行
aws sts get caller identity
,并获得本地用户的arn,则可以创建具有与服务用户相同权限的其他iam用户。或者,您也可以创建一个基于用户名+密码的用户,并在代码库中处理不同的连接字符串。选择权在你,我会做第一个选择。
"arn:aws:iam::123456789012:role/awesome-service-dev-us-east-1-lambdaRole"