2026年6月17日

2026年6月17日

WordPressのGDPR対応とクッキー同意バナーを実装する方法

はじめに

EU一般データ保護規則(GDPR)はEU在住ユーザーの個人データを保護するための法令で、違反時には年間売上高の4%または2000万ユーロの高額な制裁金が科せられます。WordPressサイトでGDPRに準拠するには、クッキー同意の明示的な取得・Google Analyticsの条件付きロード・プライバシーポリシー整備・データ削除機能の実装が必要です。

症状・原因

  • サイトがGoogle Analyticsを同意なしにロードしており、GDPR違反の可能性がある
  • ユーザーのデータ削除リクエストを手動で処理する体制が整っていない
  • プラグインが設定しているクッキーの種類を把握できていない

解決手順

ステップ1:localStorageを使ったクッキー同意バナーを実装する

ページ再読み込みを避けながらユーザーの同意状態を管理するバナーの実装です。

<?php
// functions.php に追加 ─ クッキー同意バナーのHTML出力

add_action( 'wp_footer', function() {
    // localStorageに同意済みフラグがある場合はバナーを非表示にする
    ?>
    <div id="cookie-consent-banner" style="display:none; position:fixed; bottom:0; left:0; right:0;
         background:#1d2327; color:#fff; padding:16px 24px; z-index:9999;
         display:flex; align-items:center; gap:16px; flex-wrap:wrap;">
        <p style="margin:0; flex:1; min-width:200px;">
            当サイトはCookieを使用してユーザー体験を向上させています。
            詳細は<a href="/privacy-policy/" style="color:#72aee6;">プライバシーポリシー</a>をご覧ください。
        </p>
        <div style="display:flex; gap:8px;">
            <!-- 全て受け入れ -->
            <button id="consent-accept-all" style="background:#0073aa; color:#fff;
                    border:none; padding:8px 16px; border-radius:3px; cursor:pointer;">
                全て受け入れる
            </button>
            <!-- 必須のみ(マーケティングCookieを拒否) -->
            <button id="consent-accept-necessary" style="background:#3c434a; color:#fff;
                    border:none; padding:8px 16px; border-radius:3px; cursor:pointer;">
                必須のみ
            </button>
        </div>
    </div>
    <script>
    (function() {
        var banner  = document.getElementById('cookie-consent-banner');
        var consent = localStorage.getItem('cookie_consent'); // 同意状態を取得する

        if (!consent) {
            banner.style.display = 'flex'; // 未同意ならバナーを表示する
        }

        document.getElementById('consent-accept-all').addEventListener('click', function() {
            localStorage.setItem('cookie_consent', 'all'); // 全て同意を記録する
            banner.style.display = 'none';
            // Google Analyticsを動的にロードする
            loadGoogleAnalytics();
        });

        document.getElementById('consent-accept-necessary').addEventListener('click', function() {
            localStorage.setItem('cookie_consent', 'necessary'); // 必須のみ同意を記録する
            banner.style.display = 'none';
        });
    })();
    </script>
    <?php
} );

ステップ2:Google Analytics・GTMを同意後にのみロードする

同意取得前にトラッキングスクリプトを実行しないよう条件付きロードを実装します。

<?php
// functions.php に追加 ─ 同意条件付きのGA・GTMロード

add_action( 'wp_head', function() {
    $ga_id  = 'G-XXXXXXXXXX'; // Google Analytics 測定ID
    $gtm_id = 'GTM-XXXXXXX';  // Google Tag Manager コンテナID
    ?>
    <script>
    // GA4 を同意状態に基づいて条件付きロードする
    function loadGoogleAnalytics() {
        // すでにロード済みの場合は二重実行を防ぐ
        if (window.gtag) return;

        var script = document.createElement('script');
        script.async = true;
        script.src = 'https://www.googletagmanager.com/gtag/js?id=<?php echo esc_js( $ga_id ); ?>';
        document.head.appendChild(script);

        window.dataLayer = window.dataLayer || [];
        window.gtag = function() { window.dataLayer.push(arguments); };
        gtag('js', new Date());
        gtag('config', '<?php echo esc_js( $ga_id ); ?>', {
            // GDPRに配慮してIPアドレスを匿名化する(GA4はデフォルトで匿名化)
            'anonymize_ip': true,
        });
    }

    // ページ読み込み時に同意済みの場合はすぐにGAをロードする
    if (localStorage.getItem('cookie_consent') === 'all') {
        loadGoogleAnalytics();
    }
    </script>
    <?php
} );

ステップ3:wp_add_privacy_policy_contentでプライバシーポリシーを統合する

プラグインが収集するデータをWordPressのプライバシーポリシーページに自動追記します。

<?php
// functions.php またはプラグインファイルに追加

add_action( 'admin_init', function() {
    // プラグインが収集するデータの説明をプライバシーポリシーに追加する
    $content = wp_kses_post( '
        <h2>収集するデータについて</h2>
        <p>当サイトは以下のデータを収集します:</p>
        <ul>
            <li><strong>Google Analytics</strong>: ページビュー・セッション・IPアドレス(匿名化済み)。
            同意した場合のみ収集されます。保持期間:26ヶ月。</li>
            <li><strong>お問い合わせフォーム</strong>: 氏名・メールアドレス・メッセージ内容。
            回答完了後60日間保持し、その後削除します。</li>
            <li><strong>Eコマース</strong>: 注文情報・請求先住所。法的要件により7年間保持します。</li>
        </ul>
        <p>データの削除・エクスポートをご希望の場合は
        <a href="/contact/">お問い合わせページ</a>からリクエストしてください。</p>
    ' );

    // ポリシーページの草稿に追記する(管理者が確認して公開する)
    wp_add_privacy_policy_content( 'My Theme / Plugin', $content );
} );

ステップ4:個人データのエクスポート・削除機能を実装する

GDPRが要求するデータポータビリティ(エクスポート)と消去権(削除)の実装です。

<?php
// functions.php に追加 ─ データエクスポーター登録

// 個人データエクスポーターを登録する(ツール→個人データのエクスポートで使用)
add_filter( 'wp_privacy_personal_data_exporters', function( $exporters ) {
    $exporters['my-plugin'] = [
        'exporter_friendly_name' => 'My Plugin データ',
        'callback'               => 'my_plugin_data_exporter',
    ];
    return $exporters;
} );

function my_plugin_data_exporter( $email, $page = 1 ) {
    global $wpdb;
    $user = get_user_by( 'email', $email );

    if ( ! $user ) {
        return [ 'data' => [], 'done' => true ];
    }

    // ユーザーに関連するカスタムデータを取得する
    $rows = $wpdb->get_results( $wpdb->prepare(
        "SELECT * FROM {$wpdb->prefix}my_custom_data WHERE user_id = %d LIMIT 100",
        $user->ID
    ) );

    $data = [];
    foreach ( $rows as $row ) {
        $data[] = [
            'group_id'    => 'my-plugin-data',
            'group_label' => 'マイプラグインデータ',
            'item_id'     => 'record-' . $row->id,
            'data'        => [
                [ 'name' => '記録日', 'value' => $row->created_at ],
                [ 'name' => 'データ内容', 'value' => $row->content ],
            ],
        ];
    }

    return [ 'data' => $data, 'done' => true ];
}

// 個人データ消去ハンドラーを登録する(ツール→個人データの消去で使用)
add_filter( 'wp_privacy_personal_data_erasers', function( $erasers ) {
    $erasers['my-plugin'] = [
        'eraser_friendly_name' => 'My Plugin データ消去',
        'callback'             => 'my_plugin_data_eraser',
    ];
    return $erasers;
} );

function my_plugin_data_eraser( $email, $page = 1 ) {
    global $wpdb;
    $user = get_user_by( 'email', $email );

    if ( ! $user ) {
        return [ 'items_removed' => 0, 'items_retained' => 0, 'messages' => [], 'done' => true ];
    }

    // ユーザーの個人データを完全に削除する
    $deleted = $wpdb->delete(
        $wpdb->prefix . 'my_custom_data',
        [ 'user_id' => $user->ID ],
        [ '%d' ]
    );

    return [
        'items_removed'  => (int) $deleted,
        'items_retained' => 0,
        'messages'       => [ "ユーザー {$email} のデータを削除しました" ],
        'done'           => true,
    ];
}

ステップ5:クッキー監査 ─ プラグインが設定するクッキーを特定する

サイトで使用されているすべてのクッキーを監査し、同意バナーに記載します。

<?php
// functions.php に追加 ─ Cookieヘッダー監視とクッキーリスト出力

// Set-Cookieを送信する前にログを記録してクッキーを追跡する
add_action( 'wp_loaded', function() {
    if ( ! defined( 'COOKIE_AUDIT_MODE' ) || ! COOKIE_AUDIT_MODE ) {
        return;
    }

    // 現在のCookieをログに記録する(開発環境のみで使用すること)
    $cookies = [];
    foreach ( $_COOKIE as $name => $value ) {
        $cookies[] = [
            'name'    => $name,
            'size'    => strlen( serialize( $value ) ),
            // Cookieの種類を分類する
            'type'    => classify_cookie( $name ),
        ];
    }

    // ログファイルに出力する
    error_log( 'Cookie audit: ' . json_encode( $cookies, JSON_UNESCAPED_UNICODE ) );
} );

// Cookie名からカテゴリーを自動判定する
function classify_cookie( $name ) {
    $patterns = [
        'analytics'   => [ '_ga', '_gid', '_gat', '__utma', '__utmb', '__utmc', '__utmz' ],
        'marketing'   => [ '_fbp', '_fbc', 'fr', 'ads', 'doubleclick' ],
        'necessary'   => [ 'wordpress_', 'wp-settings', 'PHPSESSID', 'woocommerce_' ],
        'preferences' => [ 'cookielawinfo', 'viewed_cookie_policy', 'cookie_consent' ],
    ];

    foreach ( $patterns as $type => $list ) {
        foreach ( $list as $pattern ) {
            if ( strpos( $name, $pattern ) !== false ) {
                return $type;
            }
        }
    }

    return 'unknown'; // 不明なCookieは要調査
}

注意事項

  • 同意前のクッキー設定: GDPRでは明示的な同意前に非必須クッキーを設定することは原則禁止。テーマやプラグインがhead内でCookieを設定していないか確認が必要
  • 同意ログの保存: コンプライアンス証明のため、誰がいつ何に同意したかをサーバー側にも記録すること(localStorageだけでは不十分)
  • 子供のプライバシー: 13歳未満のユーザーを対象とするサービスでは保護者の同意が別途必要(COPPA/GDPR-K)

まとめ

WordPress のGDPR対応は同意バナー・条件付きGA読み込み・プライバシーポリシー統合・データ削除機能の4つを組み合わせることで実現できます。定期的なクッキー監査を実施し、新規プラグイン追加時にも同意バナーを更新することが継続的なコンプライアンス維持に重要です。関連記事:WordPressのカスタムログインページをデザインする方法

お気軽にご相談ください

お見積りへ お問い合わせへ