AMP

Управление неаутентифицированным состоянием пользователя при помощи AMP

Оглавление

Состояние пользователя — важная концепция в современном Интернете. Перечислим ряд сценариев, которые становятся возможны благодаря управлению состоянием пользователя:

  • Продавцы товаров могут создавать полезную корзину, которая показывает пользователю те же товары, которые он добавил в корзину при своем первом посещении много недель назад. Показывая пользователю товары, которые он собирался купить в прошлом, вы повышаете вероятность того, что пользователь купит товар сейчас.
  • Издатели новостей могут подбирать для пользователя рекомендуемые статьи на основании истории просмотренных им статей, что помогает заинтересовывать читателей и показывать им больше контента.
  • Владельцы сайтов могут осуществлять сбор аналитических данных, которые позволяют определить, принадлежат ли два просмотра страниц одному и тому же человеку, который просмотрел две страницы, или же двум разным людям, каждый из которых видел по одной странице. Эта информация помогает понять, насколько эффективен сайт и, в конечном итоге, как его улучшить.

Данная статья предназначена для того, чтобы помочь вам оптимизировать управление состоянием неаутентифицированного пользователя в AMP, — это позволит обеспечить «умное» перемещение пользователя между контекстами, даже если пользователь не прошел процедуру идентификации, например путем входа в систему. После рассмотрения некоторых сложностей и соображений, связанных с этой темой, в данном руководстве приводится описание способов, которыми AMP позволяет обеспечить поддержку состояния пользователя, и даются рекомендации о том, как подойти к ее технической реализации.

Вводная информация

Тема состояния пользователя заслуживает особого рассмотрения в рамках AMP, потому что AMP-страницы могут отображаться в разных контекстах — например, на вашем сайте, в поиске Google или в стороннем приложении. Переход между этими контекстами вносит ряд сложностей в управление состоянием пользователя.

Контексты отображения AMP-страниц

AMP можно рассматривать как переносимый формат контента, который позволяет быстро загружать контент в любом месте. Ниже указаны три основных контекста, в которых могут отображаться документы AMP:

  • Домен издателя
  • AMP-кеш
  • Программа просмотра AMP
Контекст Может ли выдавать традиционные страницы? Может ли выдавать AMP-страницы? Образец URL
Домен издателя Да Да https://example.com/article.amp.html
AMP-кеш Нет Да https://example-com.cdn.ampproject.org/s/example.com/article.amp.html
Средство просмотра AMP Нет Да https://google.com/amp/s/example.com/article.amp.html

Давайте рассмотрим каждую из этих ситуаций более внимательно.

Контекст № 1: домен издателя. AMP-страницы развертываются таким образом, что они изначально загружаются с сайта издателя и доступны на нем, — например, на сайте https://example.com может быть размещена страница https://example.com/article.amp.html.

Издатели могут публиковать контент как исключительно в формате AMP, так и в двух версиях (т. е. размещать AMP-контент, который дублируется «не-AMP» контентом). Такая «парная» модель требует выполнения ряда действий, позволяющих обеспечить доступность AMP-версий страниц для поисковых систем, сайтов социальных сетей и других платформ. Оба подхода к публикации полностью поддерживаются; какой подход выбрать, издатель решает самостоятельно.

ПРИМЕЧАНИЕ: Согласно только что описанной модели «парной» публикации, домен издателя (в приведенном выше примере https://example.com) является контекстом, в котором возможен доступ как к AMP-контенту, так и к традиционному контенту. Это единственный контекст, дающий такую возможность, поскольку AMP-кеши и средства просмотра AMP, описанные ниже, способны выдавать только корректно сформированный контент AMP.

Контекст № 2: AMP-кеш. Файлы AMP можно кешировать в облаке с применением стороннего кеша, что позволяет сократить время, необходимое для доставки контента на мобильное устройство пользователя.

Используя формат AMP, производители контента делают контент в файлах AMP доступным для кеширования третьими сторонами. В рамках такой модели издатели продолжают управлять своим контентом (публикуя его на своем домене, как описано выше), однако сторонние платформы могут кешировать или зеркалировать контент для обеспечения оптимальной скорости его доставки пользователям.

Как правило, контент, выдаваемый таким образом, поступает с другого домена. Например, Google AMP Cache использует для доставки контента домен https://cdn.ampproject.org, например https://example-com.cdn.ampproject.org/s/example.com/article.amp.html.

Контекст № 3: программа просмотра AMP. Формат AMP создан для поддержки встраивания в сторонние программы просмотра AMP. Это обеспечивает высокую степень взаимодействия между файлом AMP и средством просмотра, преимущества которого включают: интеллектуальную и безопасную предварительную загрузку и предварительный рендеринг контента, а также инновационные возможности, такие как перелистывание полных AMP-страниц.

Как и в случае с AMP-кешем, следует ожидать, что домен средства просмотра AMP также будет отличаться от домена издателя. Например, средство просмотра, используемое поиском Google, размещено на https://google.com и выполняет встраивание элемента iframe, который запрашивает контент издателя из Google AMP Cache.

Несколько контекстов = управление несколькими состояниями

Издатели должны быть готовы отдельно управлять состоянием пользователя в каждом контексте отображения контента. Функция AMP Client ID, которая использует файлы cookie или локальное хранилище для сохранения состояния, предоставляет AMP-страницам возможность сохранять стабильный и псевдонимный идентификатор пользователя. Для реализации этого используются файлы cookie или локальное хранилище, и AMP принимает решение, что именно использовать, в зависимости от контекста отображения контента — на выбор влияет техническая возможность управления этим состоянием в масштабе сотен или тысяч издателей.

Однако издатели AMP-страниц могут с легкостью (непреднамеренно) создавать пользовательские пути, состоящие из нескольких контекстов. Давайте вернемся к нашему предыдущему сценарию с корзиной покупок и дополним его подробностями, чтобы составить полную пользовательскую историю:

В 1-й день пользователь открывает AMP-страницу Example Inc. через поиск Google. Поиск Google загружает AMP-страницы в средстве просмотра AMP. При просмотре страницы пользователь добавляет четыре товара в свою корзину, но не выполняет выход из системы. Две недели спустя, на 15-й день, пользователь вспоминает о четырех товарах, которые он собирался купить, и решает, что пришло время сделать это. Он открывает главную страницу Example Inc по адресу https://example.com напрямую (это традиционная, не-AMP, страница) и обнаруживает, что все четыре товара все еще сохранены в его корзине.

В этом сценарии пользователь получает согласованный опыт работы с корзиной покупок, даже если он перешел от контекста средства просмотра AMP к контексту домена издателя — причем с некоторым промежутком времени между этими событиями. Это очень разумный сценарий, и, если вы разрабатываете интернет-магазин, стоит предусмотреть его поддержку; так как это сделать?

Чтобы сделать возможным этот и любой другой сценарий, связанный с состоянием пользователя, все контексты, сквозь которые проходит пользователь, должны делиться своим индивидуально поддерживаемым состоянием друг с другом. «Идеально!» — скажете вы. — «Нужно просто делиться значениями файлов cookie с идентификаторами пользователей, передавая их сквозь границы контекстов». Не все так просто: несмотря на то, что каждый из этих контекстов отображает контент, контролируемый одним и тем же издателем, каждый контекст рассматривает другой как сторонний объект, поскольку они находятся в разных доменах.

AMP's ability to be displayed in many contexts means that each of those contexts has its own storage for identifiers

Как вы увидите в дальнейшем обсуждении, пребывание в позиции третьей стороны при взаимодействии с файлами cookie может создавать проблемы в зависимости от того, какие настройки использует браузер пользователя. В частности, если в определенной ситуации сторонние файлы cookie окажутся заблокированы, это лишит нас возможности передавать информацию между контекстами. С другой стороны, если операции со сторонними файлами cookie разрешены, делиться информацией можно.

Руководство по реализации

В этом разделе представлены рекомендации по управлению состоянием пользователя. Приведенные ниже задачи представлены в виде последовательности, но в основном их можно разделить на две части:

Часть № 1: Фундаментальная реализация. Задачи 1–4 необходимы для обеспечения работы основных механизмов. Они полагаются на минимальный набор функций, необходимых для частичного достижения поставленной цели: подстановка AMP Client ID, чтение и запись файлов cookie, а также хранение бэкендовой таблицы сопоставления. Почему это лишь частичное достижение цели? Действия, описанные в этих задачах, используют операции чтения и записи файлов cookie, однако настройки браузера в определенных обстоятельствах могут блокировать это; поэтому данного набора задач, скорее всего, будет недостаточно для полного управления состоянием пользователя во всех сценариях.

После создания основы мы переходим к теме с более узким разбросом сценариев, которая, однако, предлагает для них полноценное решение.

Часть № 2: Использование Client ID при переходах по ссылкам и отправке форм: в задаче 5 вы узнаете, как использовать переходы по ссылкам и/или отправку форм для передачи информации AMP Client ID сквозь контекстные границы, когда пользователь непосредственно переходит с одной страницы на другую.

ВНИМАНИЕ! В представленном далее руководстве по реализации рассказывается, как использовать файлы cookie и работать с ними. Обязательно ознакомьтесь с важными советами, приведенными в разделе Настоятельно рекомендуемые методы.

Прежде чем начать

При разборе технических инструкций, представленных ниже, мы исходим из того, что вы будете привязывать состояние пользователя к постоянному идентификатору, представляющему пользователя. Например, идентификатор может выглядеть как n34ic982n2386n30. Далее на стороне сервера вы ассоциируете n34ic982n2386n30 с любым набором данных о состоянии пользователя (например, с данными о содержимом корзины пользователя, списке ранее прочитанных статей или другими данными, в зависимости от сценария).

Для простоты понимания в остальной части этого документа мы будем называть соответствующие идентификаторам строки символов более удобочитаемыми именами, начинающимися со знака доллара ($):

n34ic982n2386n30 ⇒ $sample_id

Наш сценарий: в данном руководстве мы будем работать с примером реализации простого отслеживания просмотров страниц (т. е. аналитики), с помощью которой мы хотим производить максимально точный подсчет пользователей. Это означает, что, даже если пользователь обращается к контенту конкретного издателя из разных контекстов (в том числе с переходом между AMP-страницами и традиционными страницами), мы хотим сделать так, чтобы эти посещения засчитывались под уникальным идентификатором пользователя, который не будет отличаться от идентификатора того же пользователя, просматривающего исключительного традиционные страницы того же издателя.

Предположение о доступности стабильных значений файлов cookie: мы также исходим из того, что пользователь использует одно и то же устройство и браузер и не использует режим инкогнито или приватный режим браузера, — это позволяет полагаться на то, что сохраненные значения файлов cookie будут доступны в сеансах пользователя по прошествии времени. Если эти условия не соблюдены, описываемые методики не будут работать. Если того требует сценарий, управление состоянием пользователя следует осуществлять на основе его аутентифицированной (то есть вошедшей в систему) личности.

Представленные ниже концепции могут быть расширены на другие сценарии использования: хотя мы фокусируемся только на аналитическом сценарии, концепции, представленные ниже, могут быть перепроектированы под другие кейсы, где требуется управление состоянием пользователя в разных контекстах.

Задача 1. Создание идентификатора и отправка аналитических запросов на традиционные (не-AMP) страницы, размещенные на домене издателя

Начнем с подключения аналитики к традиционным страницам, загружаемым с домена издателя. Этого можно достичь разными способами: например, с помощью пакета аналитических функций, такого как Google Analytics или Adobe Analytics, или путем написания собственной реализации.

Если вы используете пакет аналитики от поставщика: скорее всего, такой пакет создает файлы cookie и передает запросы, используя собственный код конфигурации и API. В этом случае все равно ознакомьтесь с описанными ниже этапами, чтобы убедиться, что они согласуются с вашей реализацией аналитических функций, но будьте готовы к тому, что вам не придется вносить каких-либо изменений в рамках этой задачи.

В оставшейся части данной задачи даются советы по созданию собственной реализации средств аналитики.

Если у вас есть «не-AMP» страницы, загружаемые с домена вашего издателя, создайте постоянный и стабильный идентификатор, который будет использоваться на этих страницах. Обычно это реализуется с помощью основных файлов cookie.

Для целей нашего примера предположим, что вы установили файл cookie под названием uid («идентификатор пользователя»), который будет создаваться при первом посещении пользователя. При последующих посещениях будет выполняться чтение значения, которое было установлено при первом посещении.

Это означает, что у традиционных страниц в домене издателя может быть два состояния:

Ситуация № 1: первое посещение. При первом переходе на традиционную страницу файл cookie отсутствует. Если вы проверили наличие cookie до того, как он был установлен, соответствующий uid cookie не будет содержать значений:

> document.cookie
> ""
> 

В какой-то момент исходной загрузки cookie будет установлен, поэтому, если выполнить проверку после загрузки страницы, вы увидите, что значение установлено:

> document.cookie
> "uid=$publisher_origin_identifier"
> 

Ситуация № 2: последующее посещение. Сookie уже установлен. Поэтому, если вы откроете консоль разработчика на странице, вы увидите:

> document.cookie
> "uid=$publisher_origin_identifier"
> 
Отправка аналитических запросов

После создания идентификатора вы можете включить его в аналитические запросы, чтобы начать отслеживать просмотры страниц.

Конкретная реализация этого будет зависеть от вашей желаемой конфигурации, но, как правило, следует отправлять на аналитический сервер запросы, которые включают полезные данные в URL самого запроса. Вот пример, который также показывает, как включить в запрос значение вашего cookie:

https://analytics.example.com/ping?type=pageview&user_id=$publisher_origin_identifier

Обратите внимание, что в приведенном выше примере идентификатор пользователя указывается в специальном параметре запроса user_id:

user_id=$publisher_origin_identifier

Применение user_id здесь должно основываться на том, какое значение ожидает и обрабатывает ваш аналитический сервер; оно не привязано напрямую к названию файла cookie, хранящего идентификатор локально.

Задача 2. Создание идентификатора и отправка запросов аналитики на AMP-страницы с заменой Client ID в запросах amp-analytics

Переходя к AMP-страницам, давайте посмотрим, как создавать и передавать идентификатор для функций аналитики. Он будет работать независимо от контекста, в котором просматривается AMP-страница, поэтому данный раздел распространяется на любую AMP-страницу, независимо от того, просматривается ли она с домена издателя, выдается через AMP-кеш или отображается в средстве просмотра AMP.

При использовании функций, требующих Client ID, AMP будет выполнять скрытую работу по генерированию и сохранению значений Client ID, а также передаче их функциям, которые в них нуждаются. Одна из важнейших функций, способных использовать AMP Client ID, — это amp-analytics; именно она и понадобится нам для реализации нашего сценария по подключению аналитики.

На AMP-страницах создайте запрос amp-analytics, содержащий Client ID:

Конфигурация amp-analytics выглядит так: https://analytics.example.com/ping?type=pageview&user_id=${clientId(uid)}
То, что передается по сети, выглядит так: https://analytics.example.com/ping?type=pageview&user_id=$amp_client_id

В этом случае ${clientId(uid)} заменяется фактическим значением, которое либо генерируется средствами AMP «на лету», либо будет заменено тем, что браузер пользователя ранее сохранил локально.

Обратите внимание на то, что параметр, передаваемый в подстановку Client ID (${clientId(uid)), называется uid. Его название совпадает с именем файла cookie, которое использовалось на домене издателя в Задаче 1, и мы делаем это специально. Для обеспечения наиболее гладкой интеграции вам следует применять такую же методику.

Что касается остальной части реализации amp-analytics: чтобы получить более подробную информацию о том, как настроить запросы amp-analytics или изменить запросы, используемые вашим поставщиком аналитики, обратитесь к документации по настройке amp-analytics. Можно продолжить модифицировать запрос для передачи дополнительных данных, которые вы можете определять вручную или получать с помощью других замен AMP.

Полезно знать: Почему мы использовали имя uid для параметра, переданного в функцию Client ID? Параметр, который принимает подстановка clientId(...), используется для указания области действия. Вы можете использовать функцию Client ID во многих сценариях и, как следствие, генерировать множество идентификаторов Client ID. Параметр позволяет различать эти ситуации, поэтому вы используете его, чтобы указать, для какого сценария вам нужен Client ID. Например, если вы хотите отправлять разные идентификаторы третьим сторонам (таким, как рекламодатели), это можно реализовать с помощью параметра области действия.

Что касается домена издателя, «областью действия» проще всего считать название, которое вы присвоили файлу cookie. Рекомендуя использовать значение uid для параметра Client ID здесь (в задаче 2), мы действуем согласованно с решением применять cookie под названием uid в задаче 1.

Задача 3. Обработка аналитических запросов со страниц на домене издателя

Благодаря настройке, выполненной в рамках задач 1 и 2, когда пользователь обращается к AMP-версии страницы (в любом контексте) или к традиционной странице на домене издателя, аналитический запрос будет использовать один и тот же идентификатор. Выбор в задаче 2 «области действия» Client ID, название которой совпадает с именем файла cookie, установленного в задаче 1, позволяет AMP задействовать тот же файл cookie.

Это проиллюстрировано в таблице ниже:

Аналитический запрос, поступающий с традиционной страницы на домене издателя, выглядит так: https://analytics.example.com/ping?type=pageview&user_id=$publisher_origin_identifier
Аналитический запрос, поступающий с AMP-страницы на домене издателя, выглядит так: https://analytics.example.com/ping?type=pageview&user_id=$publisher_origin_identifier
В этом случае это идентичный запрос! При выборе значения области действия uid используется базовое значение cookie-файла uid$publisher_origin_identifier.

Задача 4. Обработка аналитических запросов из контекстов AMP-кеша или средства просмотра AMP и (при необходимости) создание сопоставлений идентификаторов

Когда в рамках задачи 2 мы настраивали аналитические запросы для передачи данных с AMP-страниц, отображаемых в AMP-кеше или средстве просмотра AMP, мы также создали проблему. Как уже упоминалось, контексты AMP-кеша и средства просмотра AMP отличаются от контекста домена издателя и, следовательно, требуют других способов создания и хранения идентификаторов. Чтобы при обработке запросов из этих контекстов избежать проблем, таких как завышение количества пользователей, мы предпримем некоторые действия, направленные на максимально частое согласование идентификаторов.

Чтобы лучше понять предпринимаемые нами действия, сперва стоит объяснить, как именно возникает проблема завышения количества.

Разбор проблемы

Рассмотрим следующую последовательность:

  1. Пользователь посещает AMP-страницу в контексте средства просмотра AMP, например https://google.com/amp/s/example.com/article.amp.html. Поскольку средство просмотра AMP не имеет доступа к файлу cookie uid на домене издателя, для идентификации пользователя создается случайное значение $amp_client_id.
  2. Затем тот же пользователь посещает страницу на домене издателя https://example.com. Как описано в задаче 3, пользователь идентифицируется с помощью $publisher_origin_identifier.

События (1) и (2) происходят в разных источниках (или контекстах), следовательно, общее состояние отсутствует, а $amp_client_id отличается от $publisher_origin_identifier. К чему это приводит? (1) — это сеанс просмотра страницы, который выглядит как один пользователь, а (2) — еще один сеанс просмотра страницы, который выглядит так, словно исходит от другого пользователя. По сути, несмотря на то, что пользователь продолжил взаимодействовать с контентом https://example.com, мы завышаем количество пользователей и пользователь события (1) выглядит как «отказ» (одиночное посещение страницы).

Стратегия решения

Чтобы решить проблему завышения, используйте следующую стратегию, эффективность которой зависит от того, разрешено ли чтение или запись сторонних файлов cookie:

  • Немедленное согласование идентификатора: если вы можете получить доступ к файлам cookie на домене издателя или изменить их, используйте или создайте идентификатор домена издателя и игнорируйте все идентификаторы, включенные в аналитический запрос. Далее вы сможете успешно сопоставить действия в рамках двух контекстов.
  • Отложенное согласование идентификаторов: если у вас нет возможности читать и изменять идентификаторы домена издателя (то есть файлы cookie), вернитесь к использованию AMP Client ID, который уже включен в аналитический запрос. Вместо того чтобы использовать или создавать новый идентификатор (cookie) домена издателя (что вы не можете сделать из-за блокировки сторонних файлов cookie), используйте Client ID в качестве «псевдонима», после этого добавьте псевдоним в таблицу сопоставления. Вам не удастся сразу сопоставить активность между двумя контекстами, но с помощью таблицы сопоставления вы можете связать значение AMP Client ID с идентификатором домена издателя при следующем визите пользователя. Когда это произойдет, у вас будет информация, необходимая для того, чтобы связать активность и подтвердить, что разноконтекстные посещения страниц исходили от одного и того же пользователя. Задача 5 описывает, как создать полное решение для специфичных сценариев, в которых пользователь сразу переходит с одной страницы на другую.

Этапы реализации

На сервере проверьте наличие существующего идентификатора домена издателя

Прочитайте значения cookie, отправленные в составе аналитического запроса. В нашем примере это означает проверку наличия cookie uid с сайта example.com.

  • Если значение uid успешно прочитано, используйте его для записи аналитических данных (идентификатор записи аналитики). Из задачи 1 мы знаем, что значение этого идентификатора — $publisher_origin_identifier. Установив идентификатор записи аналитики, мы можем переходить к разделу Хранение данных.
  • Если значение uid не удалось считать, выполните указанные ниже действия с применением таблицы сопоставления.
Таблица сопоставления

Наша таблица сопоставления будет связывать значения AMP Client ID, которые отображаются в аналитических запросах, с идентификаторами домена издателя. Это выполняется следующим образом:

Идентификатор пользователя в домене издателя Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя («псевдоним»)
Происходит из идентификатора домена издателя или генерируется как потенциальное значение, если идентификатор домена издателя недоступен. Происходит из AMP Client ID

Сразу после определения того, что вам не удалось прочитать идентификатор домена издателя, проверьте содержащийся в аналитическом запросе AMP Client ID на предмет того, используется ли он уже в сопоставлении. Для этого прежде всего извлеките значение Client ID из входящего запроса amp-analytics. Например, из следующего запроса:

https://analytics.example.com/ping?type=pageview&user_id=$amp_client_id

мы извлекаем выделенную жирным шрифтом часть, соответствующую AMP Client ID: $amp_client_id.

Далее изучите таблицу сопоставления и попытайтесь найти такое же значение в столбце «псевдоним»:

Идентификатор пользователя в домене издателя Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя («псевдоним»)
$existing_publisher_origin_identifier $amp_client_id

В приведенном выше примере мы находим запись, которая уже существует. Значение, которое указано в паре с AMP Client ID, становится идентификатором записи аналитики (в данном примере это $existing_publisher_origin_identifier). Установив идентификатор записи аналитики, мы можем переходить к разделу «Хранение данных».

В противном случае, если в таблице сопоставления AMP Client ID найти не удалось, нам необходимо создать сопоставление:

  1. Сгенерируйте потенциальный идентификатор домена издателя — в дальнейших примерах будем называть его $prospective_identifier. Это значение должно создаваться так же, как создается значение на домене издателя (см. задачу 1 выше).
  2. Затем попытайтесь установить потенциальный идентификатор домена издателя в качестве файла cookie на домене издателя. Эта операция будет успешной только при возможности записи сторонних файлов cookie.
  3. Далее сохраните пару {потенциальный идентификатор домена издателя, AMP Client ID}.

Созданное нами сопоставление в итоге выглядит так:

Идентификатор пользователя в домене издателя Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя («псевдоним»)
$prospective_identifier (генерируется моментально при получении аналитического запроса) $amp_client_id (происходит из аналитического запроса)

Мы будем использовать потенциальный идентификатор домена издателя в качестве идентификатора записи аналитики, поскольку это то значение, которое ассоциировано с состоянием на домене издателя. В данном случае это $prospective_identifier, которое будет задействовано в следующем разделе «Хранение данных».

Хранение данных

Теперь, когда мы определились с идентификатором записи аналитики, можно сохранить информацию состояния пользователя (в данном случае данные аналитики) с привязкой к этому идентификатору:

{analytics record identifier, analytics data ...}

Задача 5: Использование Client ID при переходе по ссылкам и отправке форм

Как правило, если чтение и запись сторонних файлов cookie запрещены, могут возникать ситуации, когда полностью эффективное управление состоянием пользователя оказывается невозможным. Действия, которые мы предприняли в задачах 1–4, оказывают нам двойную помощь: (1) они обеспечивают полностью эффективное решение, если чтение и запись сторонних файлов cookie разрешены, и (2) они подготавливают нашу систему к использованию любой последующей возможности согласования кросс-контекстных идентификаторов, если немедленное согласование невозможно из-за настроек браузера в отношении файлов cookie.

В этой задаче мы рассмотрим дополнительную оптимизацию, которая помогает, когда пользователь меняет контексты при перемещении с одной страницы на другую с помощью ссылок или отправки форм. В таких ситуациях с помощью описанных ниже действий можно создать полностью эффективную схему управления состоянием пользователя в разных контекстах.

Использование функций подстановки

Наш подход будет использовать два вида подстановки переменных AMP.

Чтобы исходящие ссылки использовали подстановку Client ID: создайте новый параметр запроса ref_id («идентификатор реферера»), который будет отображаться в URL-адресе и содержать идентификатор исходного контекста для пользователя. Значением этого параметра сделайте подстановку AMP Client ID:

<a
href="https://example.com/step2.html?ref_id=CLIENT_ID(uid)"
data-amp-replace="CLIENT_ID"

> </a>
> 

Альтернативное решение передачи Client ID в исходящие ссылки: создайте новый параметр запроса ref_id в составе атрибута для передачи данных data-amp-addparams, а в запросах, требующих подстановки параметров, укажите эти сведения в составе data-amp-replace. Таким образом URL-адрес будет выглядеть аккуратно, а параметры, указанные в data-amp-addparams, будут добавляться динамически.

<a
href="https://example.com/step2.html"
data-amp-addparams="ref_id=CLIENT_ID(uid)"
data-amp-replace="CLIENT_ID"

> </a>
> 

Для передачи нескольких параметров запроса в data-amp-addparams разделяйте их символом &, например:

<a
href="https://example.com/step2.html"
data-amp-addparams="ref_id=CLIENT_ID(uid)&pageid=p123"
data-amp-replace="CLIENT_ID"

> </a>
> 

Чтобы обновить элементы ввода данных в форму для использования подстановки Client ID: создайте имя для поля ввода данных, например orig_user_id. Значением параметра поля формы default-value укажите подстановку AMP Client ID:

<input
  name="ref_id"
  type="hidden"
  value="CLIENT_ID(uid)"
  data-amp-replace="CLIENT_ID"
/>

Эти действия позволяют сделать Client ID доступным целевому серверу и/или доступным в качестве параметра URL на странице, куда пользователь переходит после нажатия на ссылку или отправки формы (контекст места назначения). Именем (или «ключом») будет ref_id, потому что так мы определили его в приведенных выше реализациях, и его ассоциированным значением будет Client ID. Например, перейдя по ссылке (тег <a>), представленной выше, пользователь выполнит переход к следующему URL-адресу:

https://example.com/step2.html?ref_id=$amp_client_id

Когда пользователь попадает на страницу, содержащую значение ref_id в заголовке или в виде параметра URL, у нас появляется возможность совместно обработать идентификатор ref_id с идентификатором, доступным из самой страницы (т. е. значением cookie). Если вы включите оба идентификатора в аналитический запрос, ваш сервер аналитики сможет работать с обоими значениями одновременно и, зная, что они связаны, зафиксировать эту взаимосвязь в вашем бэкенде. На следующем этапе подробно описывается, как это сделать.

Извлечение параметров запроса из URL

Используя функции подстановки, мы создаем процесс перехода по ссылкам или процесс отправки формы, который предоставляет информацию (а именно, Client ID) целевому серверу и/или передает ее в виде параметра URL-адреса, который может быть прочитан на клиенте после того, как пользователь завершит переход.

Если информация была предоставлена только серверу, например через POST-метод формы, вы можете переходить к обработке информации и отображению полученной страницы. При обработке таких данных важно использовать процедуру проверки параметров, которая подробно описана ниже.

Если информация доступна в составе URL-адреса, для ее обработки можно использовать несколько способов:

  • Обработка во время перенаправления (на стороне сервера)
  • Обработка на целевой странице (на стороне клиента)

Обработка во время перенаправления (на стороне сервера)

Чтобы выполнить обработку во время перенаправления, обработайте запрос на сервере и извлеките нужный параметр или параметры. Не забывайте выполнять процедуру проверки параметров, которая подробно описана ниже. Обработайте данные совместно со значениями файлов cookie, которые содержат другие необходимые идентификаторы, а затем перенаправьте пользователя на URL-адрес, не содержащий параметров.

Обработка на целевой странице (на стороне клиента)

Какой метод обработки нужно использовать на целевой странице — зависит от того, является ли эта страница AMP-страницей или традиционной страницей.

Обновление AMP-страницы: используйте в своей конфигурации amp-analytics функцию подстановки параметров запроса (Query Parameter) для получения значения идентификатора ref_id из URL-адреса. Функция Query Parameter принимает параметр, обозначающий «ключ» нужной пары «ключ — значение» в URL и возвращает соответствующее значение. Чтобы получить идентификатор контекста AMP-страницы, используйте функцию Client ID, как мы делали это раньше.

https://analytics.example.com/ping?type=pageview&orig_user_id=${queryParam(ref_id)}&user_id=${clientId(uid)}

При передаче по сети фактические значения будут заменены:

https://analytics.example.com/ping?type=pageview&orig_user_id=$referrer_page_identifier&user_id=$current_page_identifier

Воспользовавшись нашими примерами выше, мы получим:

$referrer_page_identifier is $amp_client_id
$current_page_identifier is $publisher_origin_id

так что фактический запрос будет следующим:

https://analytics.example.com/ping?type=pageview&orig_user_id=$amp_client_id&user_id=$publisher_origin_id

Рекомендуем проверить подлинность значений параметров запроса, выполнив действия, описанные в разделе Проверка параметров ниже.

Обновление традиционной страницы: в традиционной странице, выдаваемой с домена вашего издателя, извлеките и передайте значение ref_id, содержащееся в URL. Проверьте подлинность значения, выполнив действия, указанные в разделе Проверка параметров ниже. После этого сконструируйте аналитические запросы, которые будут содержать как orig_user_id, полученный из ref_id, так и user_id, основанный на значении идентификатора в основном cookie.

ВАЖНО!

Если вы решите обрабатывать параметры на стороне клиента (на целевой странице), целевая страница должна удалять из URL информацию, относящуюся к идентификатору, сразу же после появления возможности ее считывания.

Перед удалением параметров убедитесь, что другой код, который должен запуститься для их чтения, либо:

  • Запустился перед тем, как произойдет удаление; либо
  • Может получить доступ к месту, куда сохранил данные код, считывавший и удалявший параметры.

Чтобы сделать это на своей «не-AMP» странице, включите в нее следующий код JavaScript, который удалит все параметры запроса из URL:

var href = location.href.replace(/\?[^#]+/, '');
history.replaceState(null, null, href);

Если нужно удалять меньше параметров запроса, измените код соответственно.

Обработка нескольких идентификаторов в аналитическом запросе

По сравнению с задачей 4, где мы настроили аналитический запрос так, чтобы он содержал только одно значение идентификатора, ситуация изменилась: благодаря действиям, которые мы выполнили в рамках задачи 5, у нас уже два таких значения — orig_user_id и user_id. Далее мы рассмотрим, как обрабатывать эти идентификаторы, являющиеся частью входящего аналитического запроса.

Прежде чем мы продолжим, обязательно обратите внимание на действия, описанные в разделе Проверка параметров ниже, и убедитесь, что вы готовы доверять обоим значениям, указанным в orig_user_id и user_id.

Проверьте, присутствует ли какое-либо из значений в вашей таблице сопоставления. В нашем примере выше первый просмотр страницы происходит на AMP-странице, которая НЕ находится на домене издателя, за которым следует второй просмотр страницы, который происходит на домене издателя. В результате значения параметров аналитического запроса будут выглядеть так:

Сценарий № 1: расположение идентификаторов при отправке аналитического запроса со страницы на домене издателя

Идентификатор пользователя в домене издателя Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя («псевдоним»)
Как он выражен в аналитическом запросе user_id=$publisher_origin_id orig_user_id=$amp_client_id
Ключ параметра user_id orig_user_id
Значение параметра $publisher_origin_id $amp_client_id

Обратите внимание, что идентификатор, полученный при первом просмотре страницы, соответствует правому столбцу, а идентификатор, полученный при втором просмотре страницы, находится в среднем столбце, в соответствии с тем, как был сконструирован описанный выше образец процесса.

Если вместо этого пользователь начинает со страницы, загружаемой с домена издателя, а затем переходит на AMP-страницу, которая размещается НЕ в домене издателя, то ключи параметров поменяются местами, но соответствующий им способ, которым мы ссылаемся на значения, не поменяется (т. е. $amp_client_id всегда обозначает идентификатор, хранящийся на AMP-странице, которая НЕ размещена на домене издателя):

Сценарий № 2: расположение идентификаторов, когда аналитический запрос отправляется с AMP-страницы, которая НЕ размещена на домене издателя

Идентификатор пользователя в домене издателя Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя («псевдоним»)
Как он выражен в аналитическом запросе orig_user_id=$publisher_origin_id user_id=$amp_client_id
Ключ параметра orig_user_id user_id
Значение параметра $publisher_origin_id $amp_client_id

При поиске в таблице сопоставления обращайте внимание на то, какой из сценариев используется, и ищите значения в тех столбцах таблицы сопоставления, где они должны быть. Например, если аналитический запрос отправляется со страницы на домене издателя (сценарий № 1), ищите значения с ключом user_id в столбце таблицы сопоставления «Идентификатор пользователя на домене издателя», а значения с ключом orig_user_id — в столбце «Идентификатор пользователя на AMP-странице, полученной НЕ с домена издателя (псевдоним)».

Если вы не можете найти ни одно из значений идентификатора в своей таблице сопоставления, создайте новое сопоставление:

  • Если аналитический запрос поступает со страницы на домене вашего издателя, в качестве идентификатора записи аналитики вам следует выбрать значение, соответствующее uid, а в качестве «псевдонима» — значение orig_uid.
  • Если аналитический запрос поступает не со страницы на домене вашего издателя, в качестве значения «псевдонима» для таблицы сопоставления вам следует выбрать значение, соответствующее uid. Затем выполните оставшиеся инструкции в Задаче 4, чтобы создать потенциальный идентификатор домена издателя и попытаться сохранить это значение в виде файла cookie на домене источника.
Проверка параметров

Значения, включенные в URL-адрес, могут быть злонамеренно изменены, искажены или по иной причине отличаться от ожидаемых вами значений. Действия по намеренному искажению значений называются подделкой межсайтовых запросов. Когда вы «перенаправляете» значения, бывшие частью URL-адреса, обязательно выполняйте проверку реферера, чтобы убедиться, что вы можете доверять этим значениям. Это не менее важно, чем проверять, что аналитические запросы, которые получает ваш аналитический сервер, поступают с тех страниц, с которых вы ожидаете их получать.

Например, в действиях, описанных выше, мы создали URL-адрес, предназначенный для перехода пользователя на соответствующую страницу:

https://example.com/step2.html?orig_user_id=$amp_client_id

Однако существует вероятность того, что пользователь или злоумышленник изменит этот URL на следующий:

https://example.com/step2.html?orig_user_id=$malicious_value

Вам необходимо удостовериться, что вы обрабатываете только адреса с $amp_client_id, но не адреса с $malicious_value.

Рекомендуемые действия по проверке значений, получаемых в виде параметров URL-запроса: удостоверьтесь, что реферер целевой страницы совпадает с URL-адресом, который вы ожидаете увидеть. Как правило, это адрес, уже «засветившийся» в корректном CORS-запросе с ранее виденным идентификатором. Рекомендуется принимать только опознанные таким образом идентификаторы.

На традиционной (не-AMP) странице проверьте document.referrer непосредственно на стороне клиента или передайте его значение в составе аналитического запроса, чтобы иметь возможность проверить его на стороне сервера. Если значение реферера является тем, которому вы можете доверять, то вы можете принять и обработать значения, полученные из URL-адреса целевой страницы (например, в приведенном выше примере это orig_user_id).

Для AMP-страниц обработка на стороне сервера — единственный доступный вариант. Используйте переменную подстановки Document Referrer, чтобы передать значение реферера в составе аналитического запроса. Чтобы проиллюстрировать это, взгляните на аналитический запрос, который может отправить целевая страница. Он содержит (1) значение Client ID текущей страницы, (2) переданное в URL-адресе значение, которое мы установили как Client ID на странице-реферере и (3) собственно информация о реферере для проверки значения (2): https://analytics.example.com/ping?type=pageview&orig_user_id=${queryParam(ref_id)}&user_id=${clientId(uid)}&referrer=${documentReferrer}

Если вы не можете доверять рефереру, отклоняйте любые значения, предоставленные посредством параметров URL, и не используйте их.

Настоятельно рекомендуемые практики

Сохраняйте только одну ассоциацию

Следует поддерживать только одну связь между идентификаторами любых двух контекстов. Если AMP Client ID, который вы ранее ассоциировали с файлом cookie или другим выданным вами идентификатором пользователя, появляется в паре с новым файлом cookie или выданным вами идентификатором пользователя, следует полностью удалить состояние, которое было сохранено в связи с предыдущим файлом cookie и идентификатором пользователя.

Эти действия помогут соблюсти ожидания пользователей в вопросах конфиденциальности. Как подробно описано в предыдущих разделах, управление состоянием пользователя в AMP часто включает в себя хранение и привязку различных идентификаторов в различных контекстах отображения контента AMP. Этой ситуацией никогда не следует злоупотреблять для восстановления данных или выполнения отслеживания — действий, которые являются неожиданными для пользователя или о которых вы явно не предупредили его, например после того, как пользователь удалил свои файлы cookie для ваших сайтов.

Следует соблюдать все действующие настройки конфиденциальности, доступные пользователю, включая настройки, удаляющие все cookie и очищающие локальное хранилище. Ни при каких условиях AMP Client ID или инфраструктура AMP не должна использоваться для восстановления удаленного идентификатора после того, как пользователь явным образом удалил одну сторону идентификаторских взаимоотношений.

Соблюдайте местное законодательство

В некоторых юрисдикциях ассоциирование файлов cookie и/или идентификаторов из двух или более доменов может потребовать обновления вашей политики конфиденциальности, дополнительного информирования пользователей или получения согласия конечного пользователя. Практика применения AMP Client ID, который использует файлы cookie или локальное хранилище как способы долгосрочного хранения стабильного идентификатора, должна быть проанализирована каждым издателем с учетом всех применимых законов и правил, касающихся сбора, хранения и обработки данных, а также уведомления пользователей.