websitelytics

Menu

Веб-аналитика для проектов с расширенными требованиями информационной безопасности

Опубликовано: 16 авг 2023

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

В качестве инструмента веб-аналитики мы возьмем Яндекс Метрику и открытый код ее тега — metrica-tag. Но описанные ниже шаги, как некий шаблон, на мой взгляд могут быть актуальны для многих инструментов веб-аналитики. Хотя конечно же сами коды и технические решения будут отличаться.

Пусть наш проект имеет следующие характеристики:

Цель: видеть полную картину взаимодействия пользователя с сайтом.

Именно по причине таких вводных данных для решения предлагается использовать опенсорсный вариант тега Яндекс Метрики - metrica-tag. Есть в этом правда и минус - не будут доступны проприетарные модули ЯМ, в том числе вебвизор. Во всем же остальном такой путь дает гораздо больше возможностей и гибкости в интеграции и безопасности, что особенно удобно если не используется сторонний тег-менеджер (например, GTM).

Также важным моментом для безопасности является то, что вы можете загружать скрипт metrica-tag со своего сервера. И при необходимости вы можете отправлять данные только себе во внутреннее хранилище, но это отдельная история, здесь же мы рассмотрим вариант отправки данных на сервер ЯМ.

Начнем с задачи правильного сбора данных на SPA, т. е. одностраничном веб-приложении. Если вам не нужно исключать какой либо раздел на сайте, то можно воспользоваться простым подходом — обычный сниппет Яндекс Метрикик для интеграции, плюс отслеживание маршрутизации, т. е. загрузки (просмотр) виртуальных страниц при изменении URL.

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

ym(123456, "init", {
    ...
    trackHash:true,
    ...
});

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

ym(123456, 'hit', document.location.href)

Если же вы не хотите хард-кодить коды Метрики непосредственно внутри сайта, остается вариант отредактировать сам код metrica-tag так, чтобы он работал с вашим маршрутизатором. Логика работы с SPA реализована в теге Метрики, она просто не всегда подходит для конкретного маршрутизатора.

Если у вас есть разделы сайта, на которых вы не хотите отправлять данные в ЯМ, то вам необходимо внести дополнительные модификации в код интеграции. Во-первых нужно отключить событие просмотра страницы, отправляемое автоматически при инициализации счетчика Метрики, чтобы быть уверенным, что событие просмотра страницы не будет отправляться с закрытых разделов. Для отключения используем флаг defer:

ym(123456, "init", {
    ...
    defer:true,
    ...
});

Затем с помощью метода hit отправляем событие просмотра страницы при заходе на открытые разделы, а на закрытых разделах не отправляем. Привязать отправку хита к инициализации счетчика можно с помощью метода triggerEvent и collback-функции:

document.addEventListener('yacounter123456inited', () => ym(123456, 'hit', document.location.href));

// здесь идет код сниппета Метрики

ym(123456, "init", {
    ...
    triggerEvent:true,
    ...
});

Задачу отправки данных с закрытого раздела к себе в DWH можно решить с помощью модификации открытого кода metrica-tag. Метрика предусматривает возможность инициализацию двух счетчиков с разными Id. Необходимо переопределить ендпоинт для одного счетчика, сделав его локальным. Следует отметить, что сбор и анализ сырых данных во внутреннее хранилище – это не самая тривиальная задача и по сути отдельная тема. Вам придется решить вопрос обогащения данных самостоятельно. Но при желании и наличии ресурсов это можно сделать.

Следующий шаг безопасности, это умение включать и выключать функционал Метрики "на лету", что может быть важно для одностраничнго приложения. Реализация этого возможна с помощью методов init и destruct. Если у вас один счетчик на сайте, код может выглядеть так:

// выключение Метрики
try { 
    if (Ya._metrika.getCounters().length > 0) {
       ym(Ya._metrika.getCounters()[0].id, "destruct", {})
    }
} catch(e) {console.log('looks like no YM')}


// включение Метрики
try { 
   if (Ya._metrika.getCounters().length === 0) {
       ym(123456,  "init", {
         trackLinks:true,
         trackHash:true
       });
   }
} catch(e) {console.log('looks like no YM')}

С помощью этих методов в одностраничном приложении можно отключать Метрику при заходе пользователя на закрытый раздел и включать при заходе на открытый раздел. Также с помощью этих методов можно реализовать опцию отказа пользователя от отправки данных на сервер ЯМ.

Ограничить размер текста в параметрах аналитического события, которое отправляется автоматически также можно с помощью модификации открытого кода metrica-tag. Пример javascript кода для ограничения размера и содержания текста:

// сокращаем текст до 20 символов и удаляем все кроме кириллицы и пробелов
value = value ? value.trim().slice(0,20).trim().replace(/[^а-я\s]/ig, '') : value;

Второй способ контролировать значения отправляемых автоматически событий — внедрить на отдельных элементах сайта специальный html аргумент, например, data-mtag и в нем задавать параметр события-клика по элементу. Нужно будет отредактировать открытый код metrica-tag, расширив список идентификаторов DOM, добавив атрибутdata-mtag. Дополнительно можно задать логику приоритизации выбора значения параметра события, где атрибут data-mtag идет первым.

Если вы хотите разместить отдельные счетчики на дев и прод окружение, что вполне логично, это можно с делать с помощью одного сниппета, прописав логику выбора id счетчика простым javascript выражением:

var ymCounterId = location.host.indexOf("www.example.com") > -1 ? 111111 : 222222

Результирующий сниппет инициализации Метрики может выглядеть так:

<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
var ymCounterId = location.host.indexOf("www.example.com") > -1 ? 111111 : 222222
    document.addEventListener('yacounter' + ymCounterId + 'inited', () => 
        ym(ymCounterId, 'hit', document.location.href)
    );
    var t = new Date();
    (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
    m[i].l=1*new Date();
    for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
    k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
    (window, document, "script", document.location.origin + "/tags/mtag.js" + "?" + t.getDate() + t.getMonth() 
        + t.getFullYear(), "ym");   
    ym(ymCounterId, "init", {
         trackLinks:true,
         trackHash:true,
         triggerEvent:true,
         defer: true,
    });
</script>
<!-- /Yandex.Metrika counter --> 

В данном примере также заложена логика обновления скрипта тега Метрики в кеше браузера раз в день, что удобно на период отдадки скрипта.

Если на вашем веб-сервере есть Content Security Policy не забудьте обновить настройки согласно соответствующей инструкции для Яндекс Метрики. Только в таком случае будут доступны некоторые полезные фичи Метрики, как, например, выбор цели по клику на элемент через визуальный интерфейс подгружаемый на сайт.