CloudFront может кэшировать несколько комбинаций ключей кэша на основе разных шаблонов пути.Каждое поведение кэша имеет определенный шаблон пути , которому он будет соответствовать - например, /products/*
- и затем есть поведение кэша по умолчанию для *
, которое соответствует чему-либо еще.(Этот создается по умолчанию и не может быть удален).Дистрибутивы CloudFront поддерживают до 25 уникальных шаблонов путей, каждый.Возможно, поддержка AWS может увеличить этот предел, но поскольку каждый шаблон пути поддерживает *
, а также ?
подстановочные знаки, и есть значение по умолчанию, которое перехватывает все остальное, этого вполне достаточно.
CloudFront работаетИсходя из базового предположения - с ограниченными исключениями - что все, что было отправлено источнику, может привести к тому, что источник изменяет ответ.Таким образом, почти все данные по умолчанию удаляются из исходного запроса.
Например, User-Agent
устанавливается на Amazon CloudFront
до того, как запрос будет отправлен в источник.Зачем?Поскольку, если User-Agent
было разрешено проходить, источник может изменить содержимое на основе анализа строки пользовательского агента, например, определить тип устройства (например, настольный компьютер, мобильный телефон, планшет, Smart-TV) и ответить соответствующим образом.,CloudFront не имеет возможности заранее узнать, что будет делать исходный сервер с этими значениями.Но если вам нужно, чтобы CloudFront предполагал, что изменение пользовательского агента может изменить ответ, CloudFront также необходимо будет кэшировать уникальную копию каждого объекта для каждой отдельной строки пользовательского агента, которую он видит, и использовать эти кэшированные копии только для соответствия другомуидентичный запрос.Вы можете внести в белый список заголовок User-Agent
для пересылки к источнику, и вот что происходит: CloudFront затем отправляет этот заголовок вместе с каждым запросом, а также добавляет User-Agent
к ключу кэша - который являетсянабор вещей, всегда включающий путь запроса и всегда включающий заголовки из белого списка, которые CloudFront может использовать для уникальной идентификации любого будущего запроса, который он должен считать действительно идентичным. ¹
Файлы cookie и параметры строки запроса также могут вызвать исходный серверизменить свой ответ, чтобы они также были удалены из запроса по умолчанию.Вы можете указать, какие куки, или все куки, или ни одного (по умолчанию).Вы можете указать, какие параметры строки запроса или все параметры строки запроса, или ни одного (по умолчанию).Все, что вы укажете, добавляется в ключ кэша и пересылается в источник, и CloudFront будет обслуживать только кэшированный ответ, который точно соответствует ключу кэша весь .
Заголовок Authorization
Это особенно интересный пример этого, потому что кажется, что вы заметили одну проблему, но, возможно, пропустили другую, что очень важно.
В случае GET /me
- каждый уникальный пользователь (идентифицируемый Authorization
)отправка запроса получает другой ответ.Параметры поведения кэша для пути /me
должны быть в белом списке заголовка Authorization
.Достаточно просто.
А как же GET /products/1
?Здесь будут драконы.Вы все еще должны перенаправить заголовок Authorization
в источник, поскольку в противном случае CloudFront фактически не знает, является ли это действительным, авторизованным запросом.Хотя интуиция предполагает, что можно использовать кэшированный ответ, поскольку каждый авторизованный пользователь должен получать один и тот же ответ ... CloudFront не может этого сделать, потому что вам нужен источник, чтобы проверить, можно ли положительно реагировать на этот конкретный заголовок Authorization
,Он должен быть отправлен в источник, что означает, что он должен быть частью ключа кэша.Каждое уникальное значение и действительное значение заголовка Authorization
приводит к извлечению и кэшированию CloudFront новой копии ответа, который мы надеялись использовать повторно.Фактически он будет использоваться повторно только в том случае, если тот же пользователь запросит его снова с идентичным заголовком Authorization
.
Но у CloudFront есть потенциальное решение для случая, когда нам нужно аутентифицировать / авторизовать запрос на основе какого-либо атрибута запроса, но мы не хотим ослаблять потенциальные возможности попадания в кэш путем пересылки Authorization
заголовков или файлов cookie.добавляя их к ключу кэша.
Lambda @ Edge - это расширение CloudFront, которое позволяет перехватывать, проверять и потенциально изменять запросы и ответы в 4 стратегических точках потока сигналов CloudFront -на стороне запроса, как до, так и после проверки кэша, и на стороне ответа, до того, как кэш будет записан и до того, как окончательный ответ (ударил или пропустил) возвращается зрителю.HTTP-запрос и / или ответ преобразуется в структуру данных JavaScript, и ваш пользовательский «триггерный» код Node.js может изменить поведение CloudFront.
В вашей ситуации запрос средства просмотра Lambda @ Edge *Триггер 1052 * выглядит как решение.
Триггер запроса средства просмотра имеет доступ к исходному запросу, включая заголовки, файлы cookie и параметры запроса, которые CloudFront будет удален, поскольку они нечасть ключа кеша.
Здесь, для /products/*
, вы встраиваете логику в код функции триггера для проверки заголовка Authorization
.Вы назначаете функцию триггера для поведения кэша /products/*
.
Если Authorization
допустим, вы пропускаете запрос и возвращаете управление в CloudFront, где он будет обслуживаться из кэша, если он доступен, в противном случае запрашиваетсяс вашего исходного сервера - но без наличия заголовка Authorization
, потому что для этих путей вы не пересылаете его, поэтому он не находится в ключе кэша. ³ Теперь ваши ответы можно кэшировать и использовать повторно.
Если заголовок Authorization
недействителен, вы генерируете свой ответ об отклонении непосредственно в коде триггера, а CloudFront возвращает ваш ответ неавторизованному запрашивающему, не проверяя кеш для объекта.
Но как вы проверяетезаголовок Authorization
из функции триггера?Это зависит от того, как работает ваша платформа.Если это JWT, вы можете проверить его прямо в коде функции.Но среда Lambda @ Edge имеет доступ к Интернету, отдельно от запроса, который в данный момент обрабатывает CloudFront, поэтому одним из вариантов может быть HTTP-запрос непосредственно к вашему серверу.Другой может включать поиск, который вы отправляете в сервис, такой как DynamoDB.Это сильно зависит от реализации.
Функции Lambda @ Edge запускаются в многоразовых контейнерах.Хотя повторное использование не гарантируется, наблюдение предполагает существенное повторное использование, поэтому можно ожидать, что кэширование результатов поиска заголовка Authorization
в памяти в глобальном объекте будет иметь высокую частоту обращений.
Конечно, компромисс- перевешивает ли стоимость, сложность и дополнительная задержка этого решения преимущества более низкого использования ресурсов и уменьшенной задержки, которая может возникнуть в результате потенциально высокой частоты обращений в кэш.
¹ Существует так много возможных пользователей-Агентские значения там, что User-Agent
, как правило, действительно плохой выбор для пересылки к источнику (и, следовательно, в том числе в ключе кэша), поэтому команда CloudFront предложила решение для этого конкретного случая.CloudFront может проанализировать пользовательский агент для вас и классифицировать браузер как настольный компьютер, мобильный планшет не для мобильных устройств, мобильный планшет или Smart TV, и вместо белого списка User-Agent
вы можете добавить один или несколько заголовков CloudFront-Is-*-Viewer
в белый список... что дает возможность доставлять ответы на основе общего класса используемого браузера и значительно повышает частоту обращений к кешу, которая ужасно низкая, если переадресовано User-Agent
.Вместо того, чтобы строка агента пользователя становилась частью ключа кеша, эти заголовки классификации браузера становятся частью ключа кеша, в результате чего получаются только 4 уникальные комбинации.(Теоретически, поскольку каждое значение является логическим, существует 15 возможных комбинаций, предполагая, что all-false невозможно, но я никогда не встречал больше 4).
² Существует еще одна опция для параметров строки запроса: «переслать все, кеш на основе белого списка».Это исключение из общего правила, согласно которому все, что отправлено источнику, является частью ключа кэша.Аналогичная опция недоступна для заголовков запросов или файлов cookie.
³ Итак, как вы узнаете, что запрос должен обрабатываться вашим источником, поскольку у него не будет заголовка Authorization
?Вы вводите собственный заголовок источника в CloudFront, который содержит секретный статический ключ, известный только вашему источнику, и CloudFront, устанавливающий доверие.