使用 CloudFront 的 cookie-based 身份验证(未签名的 cookie)
Using cookie-based authentication with CloudFront (NOT signed cookies)
我对 CloudFront 比较陌生,我的公司正在考虑迁移到那里的可能性。我们有很多网站有我们自己的 cookie-based 身份验证机制,非常简单:登录页面设置一个特殊的 cookie,当这个 cookie 存在时所有其他请求都会被处理,否则会被拒绝。
我们希望从 CloudFront 得到的是:
- 当对某个资源的第一个请求包含此 cookie 时,将 cookie 传递给源服务器。当没有cookie时,无论如何发送请求,这种情况下返回access denied错误是可以的。
- 缓存返回结果(如果成功)。
- 对具有此 cookie 的同一资源的所有后续请求都应从缓存中获取。
- 最好(但可选)检查 cookie 过期时间。
- 此外,应适用基于 headers 的通常 cache-control 规则。
- 登录页面请求是否被缓存,这并不重要。
我试过使用cookie白名单,但是不同的登录cookie的内容是不同的,所以不同用户的相同资源请求被分开缓存,从而产生了我们源站的全量流量。
重点是 - CloudFront 应考虑 cookie 名称和到期日期,但忽略其内容。
有什么办法可以做到吗?
不,没有。原因如下:
当网络缓存存储响应时,也会存储相应的请求。缓存不得将两个请求视为相同,除非它们确实 相同 请求。
两个请求不能被认为是相同的,除非它们实际上在所有方面都相同,当考虑发送到源的内容时。
在向源发送请求之前,CloudFront 会去除传入请求中不会转发的任何内容——headers、cookie、查询字符串——以及一切 剩下的...也就是说,将发送到源的所有内容...将在后续请求中进行比较。
原因是缓存被禁止返回无效响应,除非向源发送相同的请求,否则缓存无法知道响应是否也相同;因此,导致发送到原始服务器的内容不同的请求将永远不会收到缓存的响应,即原始服务器为(根据定义)不同的请求返回。
这就是 CloudFront 允许对 header 和 cookie 进行选择性白名单的原因:这样您就可以将实际转发的内容减少到只有源需要看到的内容,以便做出适当的响应。白名单越少,后续请求实际上相同的可能性就越大。
例如,如果您将 User-Agent:
header 转发到源站,则源服务器可能会根据应用于用户代理的试探法做出不同的响应(例如,为 IE 提供不同的内容比 Firefox 或 Chrome,以适应 IE 的怪癖)。如果您的来源需要该信息,您必须转发它,并承担随之而来的惩罚——响应将仅从缓存中提供给使用相同浏览器的另一个用户。如果您不需要用户代理字符串,则不要转发它 -- 出于这个原因。
仅按名称评估 cookie 显然与此逻辑不符。 cookie 值不同,因为用户身份不同,并且应该合理地预期来源会做出不同的响应。 (另请注意,当浏览器显示 cookie 时,它不会显示过期时间。该信息仅在服务器设置 cookie 时出现。)
如果您需要提供对缓存 objects 的经过身份验证的访问,您将需要使用 CloudFront 的一种 built-in 身份验证机制,而不是将 authentication/authorization 传递到源使用 cookie。
我对 CloudFront 比较陌生,我的公司正在考虑迁移到那里的可能性。我们有很多网站有我们自己的 cookie-based 身份验证机制,非常简单:登录页面设置一个特殊的 cookie,当这个 cookie 存在时所有其他请求都会被处理,否则会被拒绝。
我们希望从 CloudFront 得到的是:
- 当对某个资源的第一个请求包含此 cookie 时,将 cookie 传递给源服务器。当没有cookie时,无论如何发送请求,这种情况下返回access denied错误是可以的。
- 缓存返回结果(如果成功)。
- 对具有此 cookie 的同一资源的所有后续请求都应从缓存中获取。
- 最好(但可选)检查 cookie 过期时间。
- 此外,应适用基于 headers 的通常 cache-control 规则。
- 登录页面请求是否被缓存,这并不重要。
我试过使用cookie白名单,但是不同的登录cookie的内容是不同的,所以不同用户的相同资源请求被分开缓存,从而产生了我们源站的全量流量。 重点是 - CloudFront 应考虑 cookie 名称和到期日期,但忽略其内容。
有什么办法可以做到吗?
不,没有。原因如下:
当网络缓存存储响应时,也会存储相应的请求。缓存不得将两个请求视为相同,除非它们确实 相同 请求。
两个请求不能被认为是相同的,除非它们实际上在所有方面都相同,当考虑发送到源的内容时。
在向源发送请求之前,CloudFront 会去除传入请求中不会转发的任何内容——headers、cookie、查询字符串——以及一切 剩下的...也就是说,将发送到源的所有内容...将在后续请求中进行比较。
原因是缓存被禁止返回无效响应,除非向源发送相同的请求,否则缓存无法知道响应是否也相同;因此,导致发送到原始服务器的内容不同的请求将永远不会收到缓存的响应,即原始服务器为(根据定义)不同的请求返回。
这就是 CloudFront 允许对 header 和 cookie 进行选择性白名单的原因:这样您就可以将实际转发的内容减少到只有源需要看到的内容,以便做出适当的响应。白名单越少,后续请求实际上相同的可能性就越大。
例如,如果您将 User-Agent:
header 转发到源站,则源服务器可能会根据应用于用户代理的试探法做出不同的响应(例如,为 IE 提供不同的内容比 Firefox 或 Chrome,以适应 IE 的怪癖)。如果您的来源需要该信息,您必须转发它,并承担随之而来的惩罚——响应将仅从缓存中提供给使用相同浏览器的另一个用户。如果您不需要用户代理字符串,则不要转发它 -- 出于这个原因。
仅按名称评估 cookie 显然与此逻辑不符。 cookie 值不同,因为用户身份不同,并且应该合理地预期来源会做出不同的响应。 (另请注意,当浏览器显示 cookie 时,它不会显示过期时间。该信息仅在服务器设置 cookie 时出现。)
如果您需要提供对缓存 objects 的经过身份验证的访问,您将需要使用 CloudFront 的一种 built-in 身份验证机制,而不是将 authentication/authorization 传递到源使用 cookie。