使用AWS Cloudfront缓存查询时如何向api添加简单许可

保罗·泰勒

我在AWS Elastic Beanstalk上部署了一个应用程序,添加了一些简单的许可以停止滥用api,用户必须将licensekey作为字段传递

search.myapi.com/?license=4ca53b04&query=fred

如果无效,则拒绝该请求。

但是,在每月更新之前,上述查询将始终返回相同的数据,因此,我现在将search.myapi.com指向一个AWS CloudFront发行版,然后只有在未缓存查询的情况下,它才能像实际那样进入实际服务器

direct.myapi.com/?license=4ca53b04&query=fred

但是,问题在于,如果两个用户进行相同的查询,则由于许可证参数不同,Cloudfront不会将他们视为相同的查询。因此,Cloudfront缓存仅在每个用户级别上起作用,这是没有用的。

我想要做的是让CloudFront忽略用于缓存的许可证参数,而不是其他参数。我不太介意这是否意味着用户可以使用无效的许可证访问CloudFront,只要他们无法成功查询服务器即可(因为无论从CPU成本还是从货币成本上讲,CloudFront调用都很便宜,但是服务器调用很昂贵)

也许我需要在CloudFront前面进行一些检查,然后检查许可证,然后剥离许可证参数,但我不知道那是什么?

迈克尔-SQLbot

我想到了两种可能。

第一个解决方案感觉很像黑客,但是会阻止未经许可的用户成功获取未缓存的查询响应。如果响应被缓存,它将泄漏出去,但是对于原始服务器资源而言是免费的。

如果内容不敏感,而您只是想避免小偷小摸/烦恼,这可能是可行的。

对于查询参数,CloudFront允许您转发所有白名单上的缓存

因此,将白名单query(以及任何其他必填字段)列入白名单,但不要白名单license

给定查询的结果:

  • 有效许可证,高速缓存未命中:请求转到源,源返回响应,响应存储在高速缓存中
  • 有效许可证,缓存命中:来自缓存的响应
  • 无效的许可证,缓存命中:来自缓存的响应
  • 无效的许可证,高速缓存未命中:响应返回到原始,原始返回错误,错误存储在高速缓存中。

哎呀。最后一个条件是有问题的,因为如果进行相同的查询,则授权用户将收到缓存的错误。

但是,只要源为无效请求返回HTTP错误(例如),我们就可以解决此问题403 Forbidden

正如我在Amazon CloudFront Latency中解释的那样,CloudFront使用不同的计时器(非min / default / max-ttl)(默认值为t分钟)来缓存HTTP错误的响应。对于几个单独的HTTP状态代码(例如403),可以将该值设置为0(或其他值)。因此,对于源返回的错误代码,请将“错误缓存最小值” TTL设置为0秒。

至此,已经解决了缓存错误响应并将其回放到授权客户端的问题条件。

总体而言,第二个选项似乎是一个更好的主意,但需要更多的技巧,并且可能花费更多。

CloudFront具有将其与AWS Lambda连接的功能,称为Lambda @ Edge这使您可以使用在CloudFront信号流中特定触发点运行的简单Javascript脚本来分析和处理请求和响应。

  • 在检查缓存之前,将为每个请求运行查看器请求。它可以允许请求继续进入CloudFront,也可以停止处理并直接向查看者生成响应。此处生成的响应不会存储在缓存中。
  • 原始请求在检查缓存之后(仅针对缓存未命中)在请求到达原始之前运行。如果此触发器生成响应,则该响应将存储在高速缓存中,并且不会联系到源。
  • 源响应在源响应到达后运行,仅针对高速缓存未命中,并且在响应进入高速缓存之前运行。如果此触发器修改了响应,则修改后的响应将存储在缓存中。
  • 对于高速缓存未命中和高速缓存命中,“查看器响应”将在响应返回给查看器之前立即运行。如果此触发器修改了响应,则不会缓存修改后的响应。

由此,您可以看到这可能有用。

查看器请求触发器可以检查每个请求以获取有效的许可证密钥,并拒绝没有许可证密钥的请求。为此,它需要访问一种验证许可证密钥的方法。

如果您的客户群很小或很少更改,则密钥列表可以嵌入触发代码本身中。

否则,它需要验证密钥,这可以通过从触发代码中向原始服务器发送请求(运行时环境允许您的代码发出出站请求并通过Internet接收响应)来完成,或者通过在托管数据库,例如DynamoDB。

Lambda @ Edge触发器在Lambda容器中运行,并且根据流量负载,观察结果表明,到达相同边缘位置的后续请求很可能将由同一容器处理。每个容器一次仅处理一个请求,但是一旦控制权返回给CloudFront,该容器就可用于下一个请求。因此,您可以将结果缓存在每个容器内的全局数据结构中的内存中,从而大大减少了确定许可证密钥是否有效的次数。该功能允许CloudFront继续正常处理,或者通过生成自己的响应来主动拒绝无效密钥。单个触发器将使您处理的每百万个请求花费不到$ 1。

此解决方案可防止丢失或未经授权的许可证密钥实际检查缓存或向原始服务器发出查询请求。和以前一样,您希望在CloudFront缓存行为设置中自定义查询字符串白名单以license从白名单中消除,并更改错误缓存最小TTL以确保不缓存错误,即使这些错误永远不会发生。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章