【Cookie実装・GDPR対応】JavaScriptでCookieの利用同意と拒否のPopupを作る

Cookie-Popup-GDPR

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、JavaScriptでGDPR対応したCookieの利用同意と拒否のPopupを作る方法について解説していきます。

以前に、GDPR対応したCookieの利用同意と拒否のFooterバナーを作る方法について解説しています。

Popupではなく、Footerバナーを作りたい方は、こちらを参考にしてみてください。

【GDPR対応のCookie-Footerバナー】

GDPR対応したCookie-Popupの仕様を定義する

Cookieとは、WebサーバーやJavaScriptからユーザーのブラウザへ送信・保存されるデータのことです。

このCookieのデータを活用することによってWebサイトを閲覧したユーザーを識別でき、再訪問者かどうかを判断できるようになっています。

そのため、Cookieは個人情報と位置付けられており、また「足あと」とも表現されます。

GDPR(一般データ保護規則)や改正個人情報保護法により、Cookieが個人情報相当とみなされて規制されるようになったので、Cookieを使用するためにはユーザーの同意が必要となりました。

また、拒否権がないCookieのバナーやPopupは違法になるので注意が必要です。

Cookie同意取得は何が正解なのか

Cookie規制により、同意取得バナーを表示しているWebサイトが近年増えている。

しかし、バナーを表示したからといって全てが解決するというわけではない。

というのも、法令に遵守している同意取得バナーを表示させないと違法なるからだ。

・「サイトの閲覧=同意」のようにユーザーに取得可否の選択権がないもの

・「Cookie ウォール」と呼ばれる同意がないとサイト閲覧できないもの

・同意拒否ボタンの場所がわかりにくいもの

・同意拒否理由をきくもの

日本のWebサイトを見ると「拒否ボタン」がないバナーを導入している企業が多い。

しかし、ユーザーに拒否権のないバナーは違法だ。

また、拒否手続きの手間を増やす手法も違法となるため、注意しなければならない。

対してオプトイン方式は、事前にデータ取得の同意可否を行う方式だ。

NGバナーとは違い、オプトイン方式であれば「拒否ボタン」を表示できるなど、確実にユーザーに選択権がある。

そのため、改正個人情報保護法はもちろん、Cookie規制が厳しいGDPR対策としても非常に有効だ。

引用元: Cookieの同意取得の仕組みは?同意管理について分析してみた

上記の内容から、特に注意すべきGDPR対応ポイントは、拒否の機能と拒否の場合Cookieをすべて削除することだと言えそうです。

GDPR対応したCookieの利用同意と拒否のPopupを作る・実装ロジック

Cookie同意UserはCookieに保存する点と、Cookie拒否UserはCookieデータをすべて削除&拒否情報をSettionStorageで管理している点が実装の注目ポイントです。

実装ロジックは、まとめると次のとおりです。

実装ロジック

  1. 同意ボタンでCookieデータをSetする。
  2. 拒否ボタンでは、Cookieデータをすべて削除する(いつの間にかCookieもすべて破棄する)。さらに、sessionStorageにrejectFlagをSetする。
  3. 初回アクセスや、Sessionが切れたらCookiePopupを表示する。
  4. FlagでStatusを管理する。
  5. Cookie同意Userは、CookieデータのSetを確認してFlagのON/OFFを実施する。
  6. cookieSetFlagが立っているUserは、Cookie同意済みUser
  7. rejectFlagが立っているUserは、Cookie-拒否User
  8. 2つのFlagがどちらも立っていないUserは、初回アクセスUserか、有効期限・Session切れUser
  9. 2つのFlagが立っていなければ、CookiePopupを表示する。

SampleCode全文 & HTML実行イメージ

SampleCodeのHTMLを実行すると、このような画面になります。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cookie-Popup🔥</title>
    <style>

        #memberPopup {
        font-family: serif;
        font-size: 16px;
        line-height: 1.6;
        color: #fff;
        /* Default => [ display: none; ] */
        display: none;
        position: fixed;
        z-index: 1;
        left: 0;
        top: 0;
        height: 100%;
        width: 100%;
        overflow: auto;
        background-color: rgba(0,0,0,0.5);
        }

        .member-popup-content {
        background-color: #f4f4f4;
        margin: 20% auto;
        width: 50%;
        box-shadow: 0 5px 8px 0 rgba(0,0,0,0.2),0 7px 20px 0 rgba(0,0,0,0.17);
        }

        .member-popup-header h1 {
        margin: 1rem 0;
        }

        .member-popup-header {
        background: lightblue;
        padding: 3px 15px;
        display: flex;
        justify-content: space-between;
        }

        .member-popup-body {
        padding: 10px 20px;
        color: black;
        }

        /* Cookie-Policy */
      .privacy-policy-link {
        color: rgb(110, 169, 211);
      }

      /* 同意/拒否ボタンを中央寄せにする */
      .cookie-consent {
        /* inline-block を中央に寄せる */
        text-align:  center;
      }

      .cookie-agree, .cookie-reject {
        display: inline-block;
        color: #fff;
        background: dodgerblue;
        padding: 20px;
        margin: 20px;
        width: 10%;
      }

      .cookie-agree:hover, .cookie-reject:hover {
        cursor: pointer;
      }

      @keyframes hide {
        from {
          opacity: 1;
        }
        to {
          opacity: 0;
          visibility: hidden;
        }
      }
      /* メディアクエリ */
      @media screen and (max-width: 600px) {
        .cookie-consent {
          flex-direction: column;
        }
        .cookie-text {
          margin-bottom: 1em;
        }
      }
    </style>
</head>
<body>

    <h1>【Cookie実装・GDPR対応】JavaScriptでCookieの利用同意と拒否のPopupを作る</h1>

    <div id="memberPopup">
        <div class="member-popup-content">

            <div class="member-popup-header">
                <h1>Members Policy </h1>
            </div>

            <div class="member-popup-body">

                <div class="cookie-consent">
                    <div class="cookie-text">
                      当サイトではCookieを使用します。Cookieの使用に関する詳細は 
                      「<a href="https://masanyon.com/privacy-policy/" target="_blank" style="text-decoration: none;" >
                        <span class="privacy-policy-link">Privacy Policy</span>
                        </a>」
                        をご覧ください。
                        <br>
                        クッキーを受け入れるか拒否するか選択してください。
                    </div>
                    <div class="cookie-agree">YES</div>
                    <div class="cookie-reject">NO</div>
                </div>

            </div>
        </div>
    </div>

    <script type='text/javascript'>

        // Popup全体のHTML-Element
        const popup = document.getElementById('memberPopup');

        // Cookie-同意/拒否のPartsを取得する
        let cookieAgree = document.querySelector('.cookie-agree');
        let cookieReject = document.querySelector('.cookie-reject');


        // [ 処理-Flow ]

        // 1. Reject-FlagをCheckする

        // 2. Accept-FlagをCheckする

        // 3. 条件をClearしている状態ならば、Popupを画面中央に表示する


        // 1. Member-Reject-FlagをCheckする
        let rejectFlag = sessionStorage.getItem('Reject-Flag');

        console.log({rejectFlag});


        // CookieのDataを取得する
        const cookieData = document.cookie;

        console.log({cookieData});


        // 2. Member-Accept-FlagをCheckする
        let acceptFlag = false;

        const cookieDataList = cookieData.split('; '); // 綺麗に分割するために「'; '」 => 半角スペースも必要なので注意!
        console.log({cookieDataList});

        for (const cookie of cookieDataList) {
            const cookieSplit = cookie.split('=');
            console.log({cookieSplit});
              
            if (cookieSplit[0] == 'robotama-cookie') acceptFlag = true;
        }

        console.log({acceptFlag});


        // 3. 条件をClearしている状態ならば、Popupを画面中央に表示する
    
        if (rejectFlag || acceptFlag) {
            console.log('Reject or Accept済み-User');
        } else {
            console.log('初回-User or Settion切れ-User');

            PopupDisplay();
        }

        // PopupをDisplayするFucntion
        function PopupDisplay() {
            popup.style.display = 'block';
        }

        // Popupを閉じるFunction
        function PopupClose() {
            popup.style.display = 'none';
        }       

        // 有効期限(日)をSetする
        const expire = 31;

        // 1. Cookie-Set-Function => 引数は有効期限(日)
        function SetCookie (expire) {
          const current = new Date();
          expire = current.getTime() + expire * 24 * 3600 * 1000;
          
          // CookieにDataをSetする
          document.cookie = `robotama-cookie=robotama-read; expire=${expire}`;
        }

        // Cookie を拒否したときに、Cookieをすべて削除するFunction
        function DeleteAllCookie () {

          const maxAgeZero = 'max-age=0';

          for (const cookie of cookieDataList) {
            const cookieSplit = cookie.split('=');

            document.cookie = `${cookieSplit[0]}=; ${maxAgeZero}`;
          }
        }

        // YES-ボタンにCookie-Set-Eventを追加する
        cookieAgree.addEventListener('click', () => {

          SetCookie(expire);

          PopupClose();
        });

        // NO-ボタンにCookie-Delete-Eventを追加する
        cookieReject.addEventListener('click', ()=>{

          sessionStorage.setItem('Reject-Flag', true);

          DeleteAllCookie();
          PopupClose();
        });

    </script>
</body>
</html>

関連記事

JavaScript書籍 Ver. 中級-上級者向け

JavaScript書籍 Ver. 初級者向け

Twitterやってます!Follow Me!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

参考・引用

  1. 【超シンプル】ポップアップをHTMLとCSSだけで実装する
  2. 【Cookie実装】JavaScriptでCookieの利用同意と拒否のFooterバナーを作る | GDPR対策・合法
  3. Cookieの同意取得の仕組みは?同意管理について分析してみた

最近の投稿