【问题标题】:Why can't my AWS Lambda node JS app access my MongoDB Atlas cluster?为什么我的 AWS Lambda 节点 JS 应用程序无法访问我的 MongoDB Atlas 集群?
【发布时间】:2021-04-23 00:11:54
【问题描述】:

上下文:

我刚刚创建了一个 Node.JS 应用程序并在 AWS Lambda 上使用无服务器框架部署了它。

问题:

我希望该应用程序能够访问我的(免费层)MongoDB Atlas Cluster。为此,我使用mongoose

设置:

我有一个具有 AdministratorAccess 权限的 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" ,没问题,我的节点应用程序可以访问该页面并提供响应。我的应用程序可以访问 Internet,但无法访问我的 MongoDB 云实例。我的 MongoDB 集群可以从任何 IP 地址访问。

这已经达到了我的知识极限:-)

【问题讨论】:

    标签: node.js mongodb mongoose aws-lambda mongodb-atlas


    【解决方案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

    【讨论】:

    • 好的,非常感谢您,这绝对是朝着正确方向迈出的一步。如果您能指出允许此“角色”访问我在 atlas 上的 mongodb 集群的方式,我将不胜感激?我在 mongodb 上注册并允许了一个“IAM”用户,该用户在连接 url 字符串中使用了“TOKEN”和“SECRET”。但我不确定如何继续使用默认使用的这个角色,它不是我可以在 mongo 上允许的用户
    • 在 mongodb atlas 中导航到您的项目,选择您的集群,转到左侧边栏上的数据库访问并在那里创建一个 IAM 类型的用户,该用户具有读取或读写您的数据库的权限。该用户的 iam rola arn 应该是上面提到的。 “arn:aws:iam::ACCOUNT_ID:role/SLS_SERVICE_NAME-ENVIRONMENT-AWS_REGION-lambdaRole”
    • 再次感谢!!
    • @NassimBen 让我知道您最后是否能够解决您的问题,以及我的回答是否足够有帮助。顺便提一句。用户创建的用户名 + 密码类型与 iam 类型的工作方式相同,不同之处在于您必须将 urlencoded 用户名+密码添加到连接字符串中,并且 authSource 将是 admin,而不是 $external 。 docs.mongodb.com/manual/reference/connection-string
    • 如果你在终端运行aws sts get-caller-identity,得到了本地用户的arn,你可以创建另一个与服务用户具有相同权限的iam用户。或者,您也可以创建基于用户名+密码的用户并处理代码库中的不同连接字符串。选择权在你,我会做第一个选择。
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2023-04-01
    • 2019-05-25
    • 2020-12-13
    • 2018-07-05
    • 2020-12-12
    • 1970-01-01
    相关资源
    最近更新 更多