如何纯粹使用 Cognito 对用户进行身份验证以供 S3 使用

Posted

技术标签:

【中文标题】如何纯粹使用 Cognito 对用户进行身份验证以供 S3 使用【英文标题】:How do I use Cognito purely to authenticate users for S3 use 【发布时间】:2016-01-10 03:16:21 【问题描述】:

我已阅读这篇文章和 AWS 上的回复 How do I use a Cognito token with API? 还有这个how to use AWS cognito with custom authentication to create temporary s3 upload security token

我还不清楚是否有更简单的解决方案来保护 S3 访问。

我有一个移动客户端和一个 node.js 后端。客户端通过后端进行身份验证并接收 jwt 访问令牌以进一步调用我的后端。除了与我自己的后端通信之外,用户应该能够将文件上传到 S3 和从 S3 下载文件。我正在寻找最简单的解决方案,以确保只有对我的后端拥有有效访问令牌的用户才能上传到 S3。

我可以做以下事情吗(这是基于这篇博文http://blog.backspace.academy/2015/03/using-cognito-with-nodejs-part-2.html):

    客户端使用我的自定义 node.js 后端进行身份验证并从我的后端接收自定义访问令牌 我的 node.js 后端获取 CognitoID AWS 临时用户凭证。但是,AWS 文档说我们还需要一个会话令牌(大概是通过调用 CognitoSync),所以我假设我的后端也需要获取会话令牌。 我的 node.js 后端将这些临时凭据和会话令牌传递给客户端 客户端使用它们调用 S3,AWS SDK 传入凭证 + 会话令牌。

我错过了什么吗?有没有更简单的方法来做到这一点?我认为没有办法简单地让客户端将我自己的自定义 node.js 用户访问令牌传递给 AWS/S3/Cognito,并让 S3/Cognito 通过调用我自己的可以验证此令牌的 node.js API 来验证令牌。

【问题讨论】:

【参考方案1】:

你已经明白了。您可以从后端获取凭证并将 AWS 凭证传送给客户端。使用将过期的临时凭证时,您将需要会话密钥 - 而且您绝对应该在移动应用客户端中使用临时凭证。

如果您想使用您自己的后端验证用户(在您的后端使用用户名/密码),您可以使用Amazon Cognito's Developer Authenticated Identities feature。如果您的用户将使用 Facebook 进行身份验证,您只需将 Facebook 访问令牌传递给 Amazon Cognito,如 the Facebook Integration topic 中所述。

无论哪种方式,您将在 AWS 文档中看到的“标准”流程是让 Amazon Cognito 将 AWS 会话凭证直接传送到移动应用程序(而不是通过您的后端)。使用 Developer Authenticated Identities 时,移动应用程序交换 OpenID Connect 令牌(由您的后端从 Cognito 的GetOpenIdTokenForDeveloperIdentity call 检索并在响应身份验证请求时传递到移动应用程序)以调用 Cognito 的GetCredentialsForIdentity。使用 Facebook 时,您只需传入 Facebook 访问令牌而不是 OpenID 令牌。无论哪种方式,通过使用此流程,您都可以使用“标准”Cognito 获取应用程序的 AWS 凭证,如 Getting Credentials topic 中针对 iosandroidjavascript、Unity 和 Xamarin 所示。

话虽如此,您确实可以代表用户从后端获取 AWS 凭证并将其推送到客户端,但请记住,所有 AWS 移动开发工具包示例都假定您使用的是 Cognito如上面的Getting Credentials topic 所示,因此您必须考虑到这一点。如果您想查看通过您自己的后端路由凭证的示例,请参阅 API Gateway Secure Pet Store 示例(backend code、client code)

【讨论】:

斯科特,谢谢,这很有帮助。现在在我的项目中实际发生的是用户 (i) 通过 FB 注册,然后传递我的自定义临时访问令牌和自定义刷新令牌,(ii) 之后不再通过 FB 登录,而是使用刷新令牌获取新的访问令牌- 除非他们注销或删除应用程序并重新安装。这意味着,仅将 FB 访问令牌传递给 Cognito 不是一种选择。因此,我将通过我的后端调用 GetOpenIdTokenForDeveloperIdentity,并将 OpenID Connect 令牌传递给移动客户端,然后移动客户端调用 GetCredentialsForIdentity。对吧? @user753416 在您无法再次刷新 FB 令牌的情况下(因为用户没有重新使用 FB 进行身份验证),您描述的工作流程听起来是正确的。如果您遇到任何其他问题,请随时在 SO 上发布另一个问题,我们很乐意提供帮助。【参考方案2】:

我编写了来自 BackSpace Academy 的 NodeJS 和 Cordova Cognito 教程,您正在参考。当时设计的教程旨在为实施 Cognito 提供急需的指导。尽管如此,Cognito 并不总是最合适的解决方案(KISS 原则)。 我认为您的解决方案可能过于复杂:

    您不需要 Cognito 从浏览器或服务器安全地访问 S3。 联合用户(oauth/Facebook)可以直接从 浏览器或通过您的 NodeJS 应用程序。 如果您不需要 Cognito 键值数据存储,则只需使用 浏览器端的联合用户。真的需要 NodeJS 服务器吗? 如果您可以从客户端完成所有操作,则不需要 NodeJs 服务器。

我建议您考虑在客户端与联合用户一起做所有事情。这在“在浏览器中配置 Web 身份联合”下的 AWS 浏览器开发工具包文档中有详细说明。

注意!永远不要将您的 AWS 凭证放入您的代码中,包括服务器端。 始终在浏览器端和服务器端使用联合用户 (oauth),为您的 EC2 实例创建一个 IAM 角色,以连接到您的 VPC 上的 S3 终端节点.由于某些愚蠢的原因,AWS S3 浏览器示例硬编码凭证。

【讨论】:

以上是关于如何纯粹使用 Cognito 对用户进行身份验证以供 S3 使用的主要内容,如果未能解决你的问题,请参考以下文章

如何配置 AWS 用户 cognito 身份验证流程以在 Java sdk 后端生成身份令牌、访问令牌?

如何使用带有 iOS SDK 的 Facebook 身份验证通过 DynamoDB 和 Cognito 存储用户信息

“没有当前用户”:是不是甚至可以通过 Amplify 使用身份验证类型 AMAZON_COGNITO_USER_POOLS 对 AWS AppSync 进行未经身份验证的调用?

如何在 AWS Cognito 上使用未经身份验证的用户在 React 上启用 AWS 位置服务地图?

如何允许 cognito 身份验证的用户获得对 s3 存储桶的公共访问权限

使用 Cognito 进行 REST API 身份验证