AWS CloudFront - 转发用户代理但不对其进行缓存

问题描述 投票:1回答:2

我希望我的起源能够看到User-Agent标题.e.g:Gecko/20100101 Firefox/62.0 not Amazon CloudFront

在“行为”选项卡中,我可以将User-Agent标头列入白名单,因此它会正确传递到原点,但现在CloudFront会根据User-Agent缓存内容,这意味着从不同浏览器访问CloudFront端点的用户会强制CloudFront转到原点。

有没有办法配置CloudFront将一些标头传递给源,但不一定要缓存它们?

编辑:我有Accept-Language标题的类似问题。我想将它传递给原点,但我不想缓存它。我正在缓存的资产不依赖于语言,但不可缓存的内容依赖于Accept-Language标头。

http amazon-cloudfront user-agent
2个回答
3
投票

您可以使用分配给CloudFront分配的Lambda @ Edge函数(https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html)。你需要两个功能:

  1. Viewer-Request事件处理程序,它将读取User-Agent标头并将其复制到例如X-My-User-Agent。在客户端的请求到达您的Cloudfront Distribution之前,将调用Viewer-Request处理程序。
  2. Origin-Request事件处理程序,它将读取X-My-User-Agent并替换User-Agent。当Cloudfront在其缓存中未找到请求的页面并将请求发送到源时,将调用Origin-Request处理程序。

请注意,您不应将User-Agent添加到Cloudfront白名单:

您可以将CloudFront配置为根据Date和User-Agent标头中的值缓存对象,但我们不建议这样做。这些标头具有许多可能的值,并且基于其值的缓存将导致CloudFront将更多请求转发到您的源。

参考:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

Viewer-Request处理程序示例(Lambda @ Edge只能在NodeJS中编写,参考:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration):

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const customUserAgentHeaderName = 'X-My-User-Agent';
  const userAgent = headers['user-agent'][0].value;


  headers[customUserAgentHeaderName.toLowerCase()] = [
    {
      key: customUserAgentHeaderName,
      value: userAgent
    }
  ];


  callback(null, request);
};

Origin-Request处理程序示例:

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const customUserAgentHeaderName = 'X-My-User-Agent';
  const realUserAgent = headers[customUserAgentHeaderName.toLowerCase()][0].value;

  headers['user-agent'] = [
    {
      key: 'User-Agent',
      value: realUserAgent
    }
  ];


  callback(null, request);
};

0
投票

如果请求在不同的用户代理之间缓存,则在命中时,真实用户代理将根本不会传递给源。 CloudFront将只返回缓存的响应。

您提到您希望将用户代理信息发送给Elasticsearch。除非您只对遗漏的请求感兴趣,否则您不能依赖从原始应用程序收集的日志。

如果您使用Lambda @ Edge将用户代理发送为realUserAgent,但user-agent标头本身不是缓存参数,则在Miss的情况下,源仍然不会接收该数据。

我在这里看到的唯一解决方案是使用从CloudFront生成的访问日志。 CloudFront访问日志不仅包含用户代理,还包含IP地址和其他有用信息。 Hit和Miss都会记录此数据。也可以轻松设置logstash以将此信息发送给Elasticsearch。

© www.soinside.com 2019 - 2024. All rights reserved.