在设计与iOS
互动的AWS
应用时(例如S3
,CloudFront
等),管理访问这些应用的优缺点是什么?客户端与服务器上的服务?
通过"管理访问",我的意思是将私人内容上传到S3,通过Cloudfront下载私人内容。
当然,处理访问权限的任何一方都需要存储AWS
访问密钥和访问密钥。安全是其中一个问题。
我对这种设计选择对任一实现的性能和灵活性的影响同样感兴趣。
最后,是否存在实现混合方法的论据,其中客户端和服务器都直接与AWS
交互,或者实现通常与其中一个或另一个相关,但不是两者都适用?
答案 0 :(得分:10)
虽然有很多情况下你可能想要以一般方式这样做,但几乎没有任何情况你想直接从客户端这样做,因为你提到ios:
通过服务器端向AWS上传数据的优点:
安全
正如在另一个答案中已经提到的那样,如果他们试图打破这些请求,那么最初通过身份验证的请求可以为你避免歹徒和黑客的麻烦。如果数据是私有的并且您真正致力于隐私,那么在系统通过身份验证时,任何数据泄漏都会更容易被阻止。
限速,用户配额等
经过身份验证的系统的附加优势在于,您可以对来自特定来源(例如用户,组,IP等)的请求进行速率限制(如果您打算围绕相同的系统架构构建多个应用,则应用级配额)。当您直接在客户端工作时,构建这种智能并不容易。
审计线索
如果您需要跟踪谁上传了什么,何时,从何处以及更多此类信息,如果您直接在服务器上获得初始请求,这将再次更容易跟踪。
失败时的异常处理
很有可能在QA测试期间出现您无法轻易预测或遗漏严重错误的故障。处理这些服务器端更有效率,因为它在您的控制之下。当客户端出现任何此类问题时,您的客户可以升级应用程序。如果您正在处理此服务器端,则可以轻松地为许多此类错误放置/部署其他检查,从而限制错误的范围。
上场时间
同样,如其他答案中所述,您的更新可能需要一段时间才能获得批准。这极大地降低了您对关键问题的响应能力,并且在严重问题(数据泄露/隐私泄露)导致重大损失(财务/用户信任/负面评级等)的情况下难以缓解
我认为您希望直接从客户端向AWS上传数据的唯一情况是
非常频繁地上传大量数据,而无需直接处理。
如果上传一次需要花费一定数量的带宽和网络资源,则上传两次会占用资源的两倍(一次来自client --> server
,然后来自server --> AWS
)。因此,如果您经常上传大量数据(每天考虑TB),那么最终会浪费大量资源,只需将数据从一个点复制到另一个点。在这种情况下,直接推送数据S3是有意义的。但是,对于这种工作方法,您的成本节省应该足以覆盖对安全性和隐私性的担忧,对于大多数应用程序而言,情况并非如此。
你在一个有围墙的花园里
基本上,该应用程序仅适用于某些预先识别的用户,该应用程序根本不适用于任何其他人(比如说,您正在开发这个用于公司内部使用)。从本质上讲,这意味着对最终用户使用您的应用程序的动机有100%的信心。
编辑 :OP在评论中提出
乍一看,在我看来这是非常可行的。这个blog post提供了许多用例(比如提供用于阅读的通配符签名网址),使用签名网址(虽然示例位于服务器如何提供签名的URL / cookie,客户端使用这些来上传到S3或从Cloudfront下载。客户端仍然直接与AWS交互,但需要由服务器控制的权限。
.NET
中),更多信息可在AWS docs获得。
由于您要处理签名服务器端,您可以轻松处理我在帖子中提到的每个要点(速率限制,用户配额,审计跟踪等等都是可行的,因为请求最初会发生到服务器)。正如this answer提到的那样,
签名网址有助于控制谁可以访问给定文件以及他们可以访问该文件的时间。
总的来说,这应该适用于很多用例。
答案 1 :(得分:3)
安全性是我在对用户进行身份验证后将所有/大多数AWS服务身份验证放在后端的主要原因。
另一个考虑因素是在批准过程中刷新Apple Store上的应用程序所需的时间。可能需要几天时间,具体取决于Apple商店队列,您可以将更改推送到您的应用; AWS后端的更改可以随意进行。
此外,在设计与AWS服务交互的应用程序时,我总是认为传输的任何内容都可能受到损害,并且非常可能被解构您的呼叫并重建自己以满足其需求的人们使用。
(例如,在启动上传图片然后应用过滤器的照片娱乐应用程序后不久,我们注意到带有过滤器ID的日志条目,应用程序中不存在来自同一IP的过滤器ID。他们没有成功,因为他们做了没有得到认证。)
希望有所帮助。
答案 2 :(得分:3)
除了其他好的答案之外,我还想补充一点:与网络应用不同,您不能指望所有用户都拥有最新版本的应用。这意味着任何版本的应用程序调用的任何服务器URL原则上都必须永久保持活动状态。这意味着如果您想要改变您的服务器基础架构(例如从AWS迁移到其他云主机),那么您不能,因为即使您使用新网址制作应用程序的更新版本,仍然会有一些未更新的应用程序调用旧的URL。
您当然可以选择在应用中进行“强制更新”机制,直到您更新后才能使用它(这在多人游戏中很常见,但其他地方并不多)或者只是不关心你的应用程序的旧版本的少数用户,他们的生活让你感到悲惨(情节扭曲 - 他们可能会被困在你的应用程序的旧版本上,因为他们的设备无法升级到最新版本iOS
版本)。
但更好的解决方案IMO是隐藏自己服务器后面的AWS网址,因此您永远不会遇到此问题。这是一个实际的细节,你真的不应该泄漏到客户端。
答案 3 :(得分:2)
出于安全考虑,将密钥保存在无法篡改的位置非常重要:这通常意味着将密钥保留在服务器上。
以这种方式考虑您的密钥:他们授予您组织的资源访问权限。通过将密钥放在移动设备上,密钥被盗会影响组织级别的资源。而是在移动设备上使用用户级身份验证,以通过服务器上的代理授予对AWS资源的访问权限。这样,丢失用户级凭据不会导致组织级别的损失,并且更容易撤消用户级凭据。
您还提到上传到S3。 AWS有一个很好的工具,称为预签名帖子,您的服务器会生成一次性上传凭据,您的移动设备可以使用该凭据将数据上传到S3,而无需通过服务器代理数据。
示例Ruby
代码:
presigned_post = bucket.presigned_post(key: key, success_action_status: 201, acl: :public_read)