我很好奇应该如何以简约但安全的方式使用 AWS Congnito。
假设您的堆栈是 React(托管在 S3 上)、API 网关和 Lambda。
根据我的阅读,这可以通过直接导入 cognito 来完成,而无需 AWS Amplify 的所有臃肿。太棒了!
const { CognitoUserPool, CognitoUser, AuthenticationDetails } = require('amazon-cognito-identity-js')
同样,我读到 API Gateway 可以期望 Cognito 在用户身份验证时提供“访问令牌”。再说一遍,太棒了!
但是这些代币存储在哪里呢?它与浏览器无关并且安全吗?
据我所知,您的三个选项是内存中(最不安全)、会话变量(半安全)和 cookie(最安全)。
对于这些访问令牌的存储,是否有任何建议可以在安全性与简单性和最小依赖性之间取得平衡?
但是这些代币存储在哪里呢?它与浏览器无关并且安全吗?
通常在您的浏览器或移动应用程序的内存中。一些客户端库还将它们保存在会话存储中,因为它有利于不同 JS 脚本的重用,并使其能够在浏览器刷新后生存,而无需重新身份验证。
据我所知,您的三个选项是内存中(最不安全)、会话变量(半安全)和 cookie(最安全)。
我想说这恰恰相反(如果“会话变量”指的是会话存储)。
流程是这样的:
您以某种方式将您的凭据(用户名、密码、MFA 响应等)传递给 Cognito。如果您使用托管 UI,也许可以直接使用,也许使用 SRP,也许使用刷新令牌。
当你让 Cognito 相信你就是你所说的那个人时,它会返回给你一堆代币。其中,您需要将
access_token
提交给 API Gateway。通常,它适用于相对较短的时间(以分钟或小时为单位)。
您可以将此访问令牌提供给 API 网关,通常是将其放入
Authorization
标头中。
API Gateway 检查签名、时间戳和令牌范围,如果它们全部匹配授权者设置,则会将您的请求转发到集成。该集成还可以访问令牌数据,并可以执行额外的身份验证和授权步骤。
您的应用程序必须将令牌存储在某处,以便能够将其从步骤 2 传递到步骤 3。
只要令牌有效(同样,通常以分钟为单位),它就可以用来代表您做事。攻击者非常想知道这个代币的价值。
一些常见的攻击媒介是:
浏览器页面中的脚本注入(可以访问会话存储)。这可以通过有缺陷的前端库、社会工程(要求您在浏览器的控制台中运行一些代码)以及其他几种方式来完成。 “促进不同脚本的重用”也意味着恶意脚本。
混乱的代理攻击(这可以迫使您的浏览器向您的 API 网关发送恶意请求,并附带有效的 cookie)。如果可以将受害者引诱到那里,则可以从您的网站以外的攻击者控制的网站发起此类请求。他们可以利用您的网关集成代码中的错误。
如果只将访问令牌存储在 JS 内存中,攻击面会小很多。