Amplitudesは JSON 形式でデータを放り込んでおけば、グラフ作成を自由に行えます。
使い方としては邪道に思いますが、ReportingObserver で Amplitude に CSPレポートのデータを記録してみました。
データ送信のために実施したことを記載します。


ReportingObserver とは?

CSP には、report-to ヘッダがあり、指定したURLに、CSPのレポートを送付することができます。
report-to あたりの仕様は、 Reporting API 1仕様化されていて、その中にReportingObserver含まれます。
現在、2020年9月ですと、Editor’s Draftですが、一部ブラウザで実装されています。
私は以下の記事で APIの存在を知りました。


ReportingObserver で収集可能な情報

Amplitude に送信されたデータで、以下が収集できていることは確認できました。
確認に使用したブラウザは、MAC の<wbr>Google Chrome 85.0.4183.83 です。

  • csp-violation CSPの違反レポートです。

  • deprecation
    将来のリリースで機能を停止する APIが使用されていることを示すレポートです。

Reporting API - Web APIs | MDN見る限りは他のレポートも送信されそうですが、まだ確認できておりません。


実施したこと

Amplitude にレポートを送信するため、以下実施しました。

JavaScript に以下を追加

index.tsx に、以下記述を追加しました。
reportsDataして、Google Tag Manager の dataLayer 変数として設定しています。
{buffered: true}することで、ReportingObserver のインスタンスを生成する前に発生した警告も収集できます。

  • index.tsx

// -----------------------------------------------------
//@ts-ignore
const observer = new ReportingObserver((reports, options) => {
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: "Reporting-API",
    reportsData: reports
  });
}, {buffered: true});
observer.observe();

Google Tag Manager の設定

  • データレイヤー変数の作成 データレイヤー変数として以下を作成します。名称は、reportsDataなります。
    Image from Gyazo

  • GTMイベントトリガー
    続いて、GTMのイベントトリガーを作ります。 JavaScript側で"Reporting-API"指定していますので、名称を合わせます。
    Image from Gyazo

  • カスタムhtmlタグ
    以下のようなカスタムHTMLタグを追加しました。
    Image from Gyazo
    HTMLの内容は以下の通りです。

    <script>
    var  reports = {{reportsData}};
    for (var i = 0; i  < reports.length; i++) {
      // プロパティを渡してイベント送信
      var report =  reports[i];
      var body = report.body;
      body["report.url"] = report.url;
      amplitude.getInstance().logEvent(report.type, JSON.parse(JSON.stringify(body)));
    }
    </script>
    
    設定タグには、Amplitude initいうAmplitude の初期化タグを、このタグの発行前に発行するようにし、 このタグ自体は、Reporting-API イベントをトリガーに発行するようにしました。

これで、Amplitudeに記録されるようになりました。
JSON.parse(JSON.stringify(body) あたりの実装は、問題ありそうに思いますので、もうちょっと良い方法がないか検討した方がいいかもしれません。


補足. securitypolicyviolation を Listener に登録して記録する。

ReportingObserver を使う前は、以下のようにsecuritypolicyviolation EventListerを使って、Google Tag Manager から Amplitude に記録していました。
CSP レポートの記録のみであれば以下のような実装でも良いかと思います。

// Content Security Policy
document.addEventListener("securitypolicyviolation", (e) => {
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: "csp-report",
    securitypolicyviolation: {
      blockedURI: e.blockedURI,
      columnNumber: e.columnNumber,
      documentURI: e.documentURI,
      effectiveDirective: e.effectiveDirective,
      lineNumber: e.lineNumber,
      originalPolicy: e.originalPolicy,
      referrer: e.referrer,
      sourceFile: e.sourceFile,
      statusCode: e.statusCode,
      violatedDirective: e.violatedDirective,
    },
  });
});


参考

以上です。

コメント