amazon-web-services - 我很困惑如何使用 Amazon Cognito 用户池控制 API Gateway Rest API 中的访问
问题描述
我花了 2 天的时间试图了解 Amazon Cognito 访问控制背后的想法,用于我正在尝试创建的网站。它非常简单:
- 该网站允许用户创建帖子
- 任何人(匿名用户和登录用户)都应该能够看到帖子
- 只有登录用户才能创建帖子
- 只有原作者才能编辑自己的帖子
现在这是我认为我已经了解的关于 amazon cognito 的事情:
- Cognito 用户池用于休息接口,身份池用于创建具有特定策略的临时亚马逊角色,因此登录我的服务的人可以直接访问 aws 服务,例如 dynamodb 或 s3 存储桶
- 为了向我的 rest 接口发出授权请求,用户必须使用 cognito UI 登录并接收访问令牌,该令牌必须随每个请求发送到 Rest API 以验证请求
- 验证可以使用 API Gateway 中的 cognito 授权器自动完成,或者通过将访问令牌重定向到 lambda 并直接在那里验证
- 如果使用 cognito 授权器完成,则无法从 lambda 中读取用户名和其他信息
- 如果我使用 AWS Amplify 在客户端处理请求授权,访问令牌会自动更新
但我对整个过程仍有一些疑问:
- Cognito 用户名是否保证是唯一的?如果没有,我怎样才能让用户在注册或使用谷歌登录后选择一个有保证的唯一用户名?
- 访问令牌是否等同于会话 cookie?
- 如果我打算在 lambda 脚本中处理访问令牌,是否有我可以使用的库或服务?因为我还没有找到验证令牌或获取与令牌关联的用户的方法
- 为什么内置授权器不将用户信息重定向到 lambda 脚本?
- 是否有一个预建的 lambda 授权器,我可以直接插入 API 网关,允许登录用户和匿名用户向它发出请求并将用户信息重定向到 lambda 脚本?因为我在存储库或其他任何地方都找不到?
解决方案
所以,我没有所有的答案,但我有一些希望能指导你:
Cognito 用户名是否保证唯一
如果用户名/电子邮件已被使用,则用户无法注册。您需要指定用于用户名的字段(即电子邮件或用户名)
访问令牌是否等同于会话 cookie?
不,访问令牌通常authorization
通过不记名令牌策略在请求的标头中进行通信,并且 cookie 在cookie
标头中。一些服务将验证 cookie,其他服务(尤其是机器对机器)将验证authorization
标头。在某些情况下,开发人员可能会决定使这些相同,但并非总是如此。
如果我打算在 lambda 脚本中处理访问令牌,是否有我可以使用的库或服务。
如果您希望获取访问令牌的上下文(如用户名,在 JWT 字符串中编码),则可以使用 JWT 解码函数。当请求到达 lambda 时,Authorizor 已经对其进行了验证,因此您无需再次执行相同操作。
为什么内置授权器不将用户信息重定向到 lambda 脚本
因为并非所有服务都需要/想要它。更好地使用服务在解码令牌后使用上下文做他们需要的事情
是否有一个预建的 lambda 授权器,我可以直接插入 API 网关,允许登录用户和匿名用户向它发出请求并将用户信息重定向到 lambda 脚本?
这个问题表明你对休息的理解存在问题。API 应该利用 CRUD 操作;所以Create
只能授予贡献者,Read
可以公开授予,Update
只能授予所有者,Delete
只能授予所有者。以上是概括,但需要API策略;当你制定这个策略时,你会意识到没有“简单”的按钮。
一般来说,我会有 2 个 API 网关,一个用于只读目的,另一个用于管理内容。这使它变得简单,并允许您以不同的方式进行扩展(即,您可能希望您的贡献者在规模问题的情况下不被只读使用所阻止)。
此外,采用基于路径的策略可以帮助简化谁可以访问哪些资源。举个例子:
用户发送 POST 请求以/api/blog/
创建新博客(结果为/api/blog/:blogId
)。/api/blog/
端点不被任何特定贡献者“拥有” 。稍后用户进行更新/api/blog/1234-abcd
...现在您的服务必须进行额外调用以查看该资源是否归用户所有(这称为“权利”过程)。在 psuedo-sql 中,您将SELECT created_by FROM blogs WHERE id='1234-abcd'
查看该created_by
字段是否与您的用户 ID 匹配。
任何人,你都明白了 :) 如果你允许团队/多个用户修改资源的能力,这将变得更加复杂......而且我们进入了 RBAC(基于角色的访问控制),这是一个更长的话题。
抱歉跑题了,但希望这能给你更多的方向。
推荐阅读
- laravel - 面临在我的项目中集成 laravel 错误日志功能的问题
- .net - 如何在图像上绘制透明形状
- javascript - 计算音节功能
- sql - sql 交叉连接替代
- java - Java UTF-8/UTF-16LE 输入转换
- html - 为什么我的按钮没有跳到 Bootstrap 4 中的预期部分?
- sql - 命令行和 Postgres 12 psql 出现问题
- docker - 有没有办法在启动之前使用映射端口配置 docker 容器(testcontainer)?
- spring - Spring Security (3.0.5),生产中的不同行为 (SSL) - (ERR_TOO_MANY_REDIRECTS)
- amazon-web-services - SNS > AWS Lambda 异步调用队列与 SNS > SQS > Lambda