Amazon web services 云锋Lambda@edge根据查看器请求设置cookie

Amazon web services 云锋Lambda@edge根据查看器请求设置cookie,amazon-web-services,aws-lambda,amazon-cloudfront,aws-lambda-edge,Amazon Web Services,Aws Lambda,Amazon Cloudfront,Aws Lambda Edge,更新:更好地收集我的想法 我正在为查看器请求Lambda中的每个用户生成一个唯一标识符(UUID),然后根据该UUID选择要返回的缓存页面。这很有效 理想情况下,此用户将始终具有相同的UUID 我必须在查看器请求中生成该UUID,如果该UUID在该查看器请求的cookie中不存在。我还需要将UUID设置为cookie,这当然发生在响应中,而不是请求中 在没有缓存的情况下,我的服务器只是处理获取自定义头并在响应头中创建一个集Cookie 如果我想缓存页面,我没有找到处理这个问题的方法。我可以忽略缓

更新:更好地收集我的想法

我正在为查看器请求Lambda中的每个用户生成一个唯一标识符(UUID),然后根据该UUID选择要返回的缓存页面。这很有效

理想情况下,此用户将始终具有相同的UUID

我必须在查看器请求中生成该UUID,如果该UUID在该查看器请求的cookie中不存在。我还需要将UUID设置为cookie,这当然发生在响应中,而不是请求中

在没有缓存的情况下,我的服务器只是处理获取自定义头并在响应头中创建一个集Cookie

如果我想缓存页面,我没有找到处理这个问题的方法。我可以忽略缓存的请求头并提供正确的缓存页面,但是用户不会持久化该UUID,因为在他们的下一个请求中没有设置要使用的cookie

有人做过这样的事吗

我正在尝试的事情

我正在从几个角度对此进行研究,但尚未开始工作:

  • 我不知道Cloudfront中的某种设置处理从查看器请求到查看器响应的头或其他数据传递,这可以在Cloudfront中的第二个lambda中使用

  • 在查看器请求中抢先修改响应对象标头。我认为这是不可能的,因为它们返回的头文件还没有创建,除非我缺少一些内置的Cloudfront方法

  • 一个现有的某种类型的传递头,我不知道这是否是一件事,因为我对请求-响应处理的这方面不太熟悉,但值得一试

  • 可能(还没有尝试过)我可以在客户机请求lambda中创建整个响应对象,并从那里以某种方式提供缓存页面,修改响应头,然后将其传递到回调方法中

  • 这个答案确实有效,但不是一个固溶体。如果用户没有存储或服务他们的cookie,那么它将成为一个无限循环,而且如果可以避免的话,我宁愿不要在我的所有页面前面抛出重定向


    有些工作概念

  • 当Cookie中不存在UUID时,查看器请求Lambda生成UUID
  • 查看器请求Lambda在请求对象的标头上的Cookie中设置UUID。传入更新的请求对象的回调
  • UUID cookie的存在破坏了Cloudfront缓存
  • 当UUID存在时触发源请求Lambda
  • 原始请求Lambda通过
    http再次调用原始请求URL。设置UUID cookie后获取
    (40KB限制使得在查看器请求Lambda中执行此操作不切实际)
  • 查看器请求Lambda的第二个场景,看到UUID现在存在,剥离UUID cookie,然后正常继续请求
  • 如果尚未缓存,则返回第二个源请求-如果缓存,则返回缓存响应,因为不存在缓存破坏UUID-将实际页面HTML返回给第一个源请求
  • 第一个原始请求从包含HTML的
    http.get
    接收响应
  • 第一个原始请求创建自定义响应对象,其中包含来自
    http.get
    的响应主体,并使用原始UUID设置Cookie头集
  • 已设置UUID的后续调用将从cookie中删除UUID(以防止缓存破坏),并直接跳到查看器请求Lambda中的第二个场景,该场景将直接加载页面的缓存版本

    我之所以说“有点”,是因为当我尝试访问我的端点时,我会下载一个二进制文件

    编辑

    这是因为我没有设置
    内容类型
    标题。我现在只有一个302重定向问题。。。如果我克服了这个问题,我会发布一个完整的答案


    原始问题

    我在查看器请求上有一个函数,它在从缓存或服务器检索请求之前选择一个选项并在请求中设置一些内容

    这是可行的,但我希望它记住未来用户的选择。这样做的目的是简单地设置一个cookie,我可以在用户下次访问时读取它。由于这是基于查看器请求而不是查看器响应,我还没有弄清楚如何实现这一点,或者是否可以通过Lambda本身实现这一点

    Viewer Request -> 
      Lambda picks options (needs to set cookie) -> 
        gets corresponding content -> 
          returns to Viewer with set-cookie header intact
    

    我已经并且能够通过Lambda在查看器响应中成功设置cookie。这对我没有多大帮助,因为需要根据请求做出决定。毫不奇怪,将此代码添加到查看器请求中不会在响应中显示任何内容

    您是否能够添加另一个目录:在第一个cookie setter请求中,返回(从lambda)一个重定向,其中包括cookie set头,该头重定向到您的实际内容

    好的,还有很长的路要走,但是:

    • 从传入请求获取cookie指令
    • 将此设置在某个位置(缓存等)
    • 让请求获取您的对象
    • 在响应上,如果需要,还调用一个函数来读取(缓存)并在响应上设置cookie头

    我认为设置不存在的cookie的真正正确方法是返回302重定向到与
    set cookie
    相同的URI,并让浏览器重做请求。这可能不会有太大影响,因为浏览器可以重用相同的连接来“跟踪”重定向

    但是如果您坚持不这样做,那么您可以使用查看器请求触发器将cookie注入请求中,然后在查看器响应触发器中使用相同的值发出
    Set cookie

    查看器响应事件中的请求对象可以在原始请求事件中找到的位置找到,
    event.Records[0]。cf.request

    在查看器响应触发器中,结构的这一部分包含

    <
    Cookie: foo=bar; buzz=fizz
    
    Cookie: foo=bar
    Cookie: buzz=fizz