Adobe Analytics

続・SafariのITP2.x対策として別サーバー使ってクッキーを永続化する

こんにちは、エクスチュアの権泳東/コン・ヨンドン(@exturekwon)です。

以前、AA + GA : SafariのITP2.1に備えてphpでクッキーを永続化する という記事を書いたところ色々反響がありました。

・おれWordpress使ってないんだけど
・うちのサイトはそんな簡単にいじれません
・あたいJSPなのよ
・わいは静的HTMLページやねん
・拙者は(以下略
・おいどん(ry

これらをまとめてスルーするのも寂しいので、今回は別の方法です。

何をやるかというと、サブドメインで別サーバーを立てて、そこからSet-Cookieヘッダを使って永続化する方法です。

手順

1. クラウドでもオンプレでもいいのでWebアプリサーバーを用意する
2. AA/GAのクッキーを読み込んで永続化するアプリを書く
3. そのサーバーに対象サイトのサブドメインを割り当てる
4. タグマネージャーで永続化アプリを読み込む画像タグを配信する

実際にこの処理を実装したサイトは下記の私個人のブログです。

二代目俺のメモ | KWONLINE.ORG

では、以下に説明します。

Webアプリサーバーを用意する

AWSでもGCPでもオンプレでもいいので好きな鯖を立ててください。
サーバーレスにしたければAppEngineでもいいしLambdaやらHerokuやら好きなのを使いましょう。

私はGCPのCompute EngineでUbuntuインスタンスを1台立てました。
マシンスペックはトラフィックに応じてスケールさせればいいので、まずはf1-microでスモールスタートします。

クッキー永続化アプリを書く

今回も手っ取り早くPHPでやります、というか以前書いたコードを流用します。
UbuntuにApache2とPHPをaptでインストールします。

そして以前の記事で使ったPHPコードを若干改変したものをこのサーバーの /var/www/html に置きます。

まずはitp.phpです。

itp.php

<?php
$domain = '.kwonline.org';
$expire = time() + 60 * 60 * 24 * 730;
 
//Adobe Analytics
$itp_amcv = $_COOKIE['itp_amcv'];
//Cookie名にAdobeOrgIDが入ります。AdobeOrg前の%40はデコードしておく。
$org_amcv = $_COOKIE['AMCV_1234567890@AdobeOrg']; 
 
if ($org_amcv) {
    setcookie('itp_amcv', $org_amcv, $expire, '/; SameSite=None', $domain, 1, 1);
} else if ($itp_amcv) {
    //Cookieをセットするときは@を%40にエンコードしておく。
    setcookie('AMCV_1234567890%40AdobeOrg', $itp_amcv, $expire, '/; SameSite=None', $domain);
    setcookie('itp_amcv', $itp_amcv, $expire, '/; SameSite=None', $domain, 1, 1);
}
   
//Google Analytics
$itp_ga = $_COOKIE['itp_ga'];
$org_ga = $_COOKIE['_ga'];
if ($org_ga) {
    setcookie('itp_ga', $org_ga, $expire, '/; SameSite=None', $domain, 1, 1);
} else if ($itp_ga) {
    setcookie('_ga', $itp_ga, $expire, '/; SameSite=None', $domain);
    setcookie('itp_ga', $itp_ga, $expire, '/; SameSite=None', $domain, 1, 1);
}

前回と若干ソースが異なります。
setcookie関数の中の第4引数でパスを指定するんですが、パスの後ろに「; SameSite=None」 という文字列が入ってます。

これはChrome対策でして、Chrome76以降は「SameSite=None」がないクッキーはサブドメインでも送信されません。
今回はサブドメインからクッキーを読み込むのでこの対策が必要です。
※SameSite制限の詳細はここらへんを参照

私の使ってるPHPのバージョンがまだ7.2でして(SameSite属性はPHP7.3からサポート)、仕方なく無理やりSameSite=Noneするための抜け道です。。

もうひとつはこちら、itp_gif.phpです。

itp_gif.php

<?php
include_once('./itp.php');
 
//1x1ピクセルの透過gifを配信
header('Content-Type: image/gif');
echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');

こちらは前回のソースコードのままです。
itp.gifをインクルードして読み込んだ上で、1×1ピクセルの透過gifを配信するためのPHPです。

実際のタグはこのitp_php.gifに対してリクエストを送ります。

サブドメインを割り当てる

DNS設定を変更して、GCP Compute Engineの外部IPアドレスに対してサブドメイン(Aレコード)を割り当てます。
私は itp.kwonline.org というホスト名をVMに付与しました。

DNS設定については省略します。
なお、私が使ってるのはGMOペパボのムームードメインです。安いです。
そろそろGCPのCloud DNSに乗り換えようか検討中です→割りとどうでもいい

digコマンドでDNSが正しく動作してるか確認します。

$ dig itp.kwonline.org

; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> itp.kwonline.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34082
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;itp.kwonline.org.		IN	A

;; ANSWER SECTION:
itp.kwonline.org.	954	IN	A	104.198.116.99

DNSが正しく動作してる事が確認出来ました。

タグマネージャーに画像タグを登録する

さて、最後はこのitp_gif.phpの方を、画像タグとして配信すればOKです。
私はGTMを使ってるので、カスタム画像タグを「すべてのページ」と「すべてのウインドウ読み込み」の2つ登録します。

カスタム画像タグを2つ登録

1つ目はページの上部で、他のタグよりも先にitp_gif.phpの画像タグを読み込むためのタグです。
キャッシュを無効にするために、gtmcbパラメータが自動的に乱数を付与するようにしてます。

「すべてのページ」で配信

2つ目は、これまた同じitp_gif.phpをwindow.onload(ウィンドウ読み込み)で最後にロードするためのタグです。
これもキャッシュを無効にします。

「ウィンドウ読み込み」で配信

で、ここで重要なのは、Adobe Analytics/Google Anayticsのタグは、1番目のitp_gifと、2番目のitp_gifの間で配信される必要がります。
というわけで、私はAA/GAはすべてDOM Readyで配信してます。

「DOM Ready」でAnalyticsタグを配信

「すべてのページ」→「DOM Ready」→「ウィンドウ読み込み」の順番でタグが実行されるので、意図した順番にタグが発火します。
なお、スクリーンショットには映ってませんが、adobe_analyticsタグは実行前にAdobeのVistorAPIタグも実行するようにも設定してあります。

補足

なんでitp_gif.phpをページの最初と最後で2回読み込む必要があるかと言うと、、、

1回目は、既に過去に訪問した事があるSafariユーザー向けで、JSによるデフォルトクッキーが消えてる場合に、永続クッキーから訪問者IDを「復元」してあげるため。
2回目は、初回訪問で永続クッキーがまだないSafariユーザーのために、改めて永続クッキーをセットしてあげるため。

という仕様です。

最後に正しくクッキーをセット出来てるか確認します。

itp_amcvとitp_gifという名のバックアップCookieを生成

itp_amcvというAdobeのクッキーと、itp_gaというGoogleのクッキーがそれぞれ出来上がりました。
SameSite属性もNoneになってます。

なお、ITP2.2現在ではHttpOnlyとSecureは必須ではないのですが、どうせそのうち必須になるだろうという雑な予想の上でつけてます。
この状態で、元のAAのAMCVクッキーと、GAの_gaをクッキーを消して再びサイトに訪問しても、バックアップCookieから元の値が復元されるようになってます。

まとめ

前回の記事とは異なり、別サーバーをサブドメインで立てる事によって同様の処理を実現しました。
別サーバーなので、好きな言語で実装出来ます。
また、計測対象のサイトそのものを改変する必要がなく、タグマネージャーから呼び出せるため導入のハードルが下がります。
ただし、別にサーバーを用意するのでその運用コストが発生します。

エクスチュアはAdobe Analytics/Google Analyticsの他、各デジタルマーケティングテクノロジー製品の導入支援・コンサルティングを行っております。
お困りの方はこちらからお気軽にお問い合わせください。

関連記事

  1. Adobe Analytics

    AdobeAnalytics Datafeed: BigQueryのSIGN関数を使った小ワザ

    こんにちは、エクスチュアの権泳東/コン・ヨンドン(@exturekwo…

  2. Adobe Analytics

    Adobe AnalyticsとGoogle Analyticsの違い② サンプリングの有無

    こんにちは。CEOの原田です。AAとGAの違いの2段目にいきます。…

  3. Adobe Analytics

    Azure DatabricksでAdobe AnalyticsのDatafeedを分析する

    こんにちは、エクスチュアの権泳東(コン・ヨンドン)です。今回はAz…

  4. Google Analytics

    Google Tag Manager上でGoogle AnalyticsのclientIDを取得する…

    2018/4/20追記:この記事の内容は古いので、下記の新しい記事…

  5. Adobe Analytics

    Adobe Analytics:Report Builderの小技:リクエストのあるシートを丸ごとコ…

    エクセルでの定期レポートを作る際に、一度データブロックを作っておけば以…

  6. Adobe Analytics

    Adobe Analytics: DWHレポートをAWSのS3バケットに配信する

    こんにちは、エクスチュアの権泳東(コン・ヨンドン)です。今回は、A…

最近の記事

  1. 【TC19ブログ】新しいデータモデリングを解説する
  2. 【TC19ブログ】セッション紹介:DataRobot×Tab…
  3. AdobeAnalytics Datafeed: BigQu…
  4. 【TC19ブログ】Tableau Conference 20…
  5. 【TC19ブログ】Tableau Conference 20…
  1. Google Analytics

    Google Analytics StandardのデータをBigQueryで分…
  2. Adobe Analytics

    Adobe Analytics: カスタムリンク計測を1行で書く
  3. Sansan

    Sansanで名刺を取り込んだらSlackで社内共有する(Zapier利用)
  4. Adobe Analytics

    Adobe Analytics: レガシーs_code.jsのリミッターを解除し…
  5. Firebase Analytics

    Firebase AnalyticsのデータをフラットなCSVに変換するETL処…
PAGE TOP