Подтвердить что ты не робот

Проверьте, включены ли сторонние файлы cookie

У меня есть приложение, которое должно проверить, включено ли в браузере клиента сторонние файлы cookie. Кто-нибудь знает, как это сделать в JavaScript?

4b9b3361

Ответ 1

Техническая информация

Сторонние наборы & читает куки по HTTP (не в JavaScript).

Поэтому нам нужно два запроса к внешнему домену, чтобы проверить, включены ли сторонние файлы cookie:

  1. Тот, где третье лицо устанавливает куки (ы)
  2. Второй - с разным ответом в зависимости от того, отправил ли браузер куки файлы обратно той же третьей стороне во втором запросе.

Мы не можем использовать XMLHTTPRequest (Ajax) из-за модели безопасности DOM.

Очевидно, что вы не можете загрузить оба сценария параллельно, или второй запрос может быть сделан до того, как ответ первого запроса вернет его, и тестовые файлы cookie не будут установлены.

Пример кода

Дано:

  1. Файл .html находится в одном домене, и

  2. Файлы .js.php находятся во втором домене, у нас есть:

Тестовая страница HTML

Сохранено как third-party-cookies.html

<!DOCTYPE html>
<html>
<head id="head">
  <meta charset=utf-8 />
  <title>Test if Third-Party Cookies are Enabled</title>
<style type="text/css">
body {
  color: black;
  background: white none;
}
.error {
  color: #c00;
}
.loading {
  color: #888;
}
.hidden {
  display: none;
}
</style>
<script type="text/javascript">
window._3rd_party_test_step1_loaded = function(){
  // At this point, a third-party domain has now attempted to set a cookie (if all went to plan!)
  var step2Url = 'http://third-party.example.com/step2.js.php',
    resultsEl = document.getElementById('3rd_party_cookie_test_results'),
    step2El = document.createElement('script');

  // Update loading / results message
  resultsEl.innerHTML = 'Stage one complete, loading stage 2&hellip;';
  // And load the second part of the test (reading the cookie)
  step2El.setAttribute('src', step2Url);
  resultsEl.appendChild(step2El);
}
window._3rd_party_test_step2_loaded = function(cookieSuccess){
  var resultsEl = document.getElementById('3rd_party_cookie_test_results'),
    errorEl = document.getElementById('3rd_party_cookie_test_error');
  // Show message
  resultsEl.innerHTML = (cookieSuccess ? 'Third party cookies are <b>functioning</b> in your browser.' : 'Third party cookies appear to be <b>disabled</b>.');

  // Done, so remove loading class
  resultsEl.className = resultsEl.className.replace(/\bloading\b/,' ');
  // And remove error message
  errorEl.className = 'hidden';
}
</script>
</head>
<body id="thebody">

  <h1>Test if Third-Party Cookies are Enabled</h1>

  <p id="3rd_party_cookie_test_results" class='loading'>Testing&hellip;</p>
  <p id="3rd_party_cookie_test_error" class="error hidden">(If this message persists, the test could not be completed; we could not reach the third-party to test, or another error occurred.)</p>

  <script type="text/javascript">
  window.setTimeout(function(){
    var errorEl = document.getElementById('3rd_party_cookie_test_error');
    if(errorEl.className.match(/\berror\b/)) {
      // Show error message
      errorEl.className = errorEl.className.replace(/\bhidden\b/,' ');
    } else {
    }
  }, 7*1000); // 7 sec timeout
  </script>
  <script type="text/javascript" src="http://third-party.example.com/step1.js.php"></script>
</body>
</html>

Первый сторонний файл JavaScript

Сохранено как step1.js.php

Это написано на PHP, поэтому мы можем устанавливать куки при загрузке файла. (Конечно, это может быть написано на любом языке или даже в файлах конфигурации сервера.)

<?php
  header('Content-Type: application/javascript; charset=UTF-8');
  // Set test cookie
  setcookie('third_party_c_t', 'hey there!', time() + 3600*24*2);
?>
window._3rd_party_test_step1_loaded();

Второй сторонний файл JavaScript

Сохранено как step2.js.php

Это написано на PHP, поэтому мы можем читать куки на стороне сервера, прежде чем ответить. Мы также удаляем cookie, чтобы можно было повторить тест (если вы хотите поэкспериментировать с настройками браузера и повторить попытку).

<?php
  header('Content-Type: application/javascript; charset=UTF-8');
  // Read test cookie, if there
  $cookie_received = (isset($_COOKIE['third_party_c_t']) && $_COOKIE['third_party_c_t'] == 'hey there!');
  // And clear it so the user can test it again 
  setcookie('third_party_c_t', '', time() - 3600*24);
?>
window._3rd_party_test_step2_loaded(<?php echo ($cookie_received ? 'true' : 'false'); ?>);

Последняя строка использует троичный оператор для вывода литерального Javascript true или false в зависимости от того, присутствовал ли тестовый файл cookie.

Проверьте это здесь.

Доступно для вашего удовольствия от тестирования на https://alanhogan.github.io/web-experiments/3rd/third-party-cookies.html.

(В заключение: не используйте чужой сервер для тестирования сторонних файлов cookie без их разрешения. Он может самопроизвольно ломаться или внедрять вредоносное ПО. И это грубо.)

Ответ 2

Здесь чисто JS-решение, не требующее какого-либо серверного кода, поэтому оно может работать со статическим CDN: https://github.com/mindmup/3rdpartycookiecheck - первый script устанавливает cookie в коде, затем перенаправляется на второй script, который отправит сообщение в родительское окно.

Вы можете попробовать живую версию, используя https://jsfiddle.net/tugawg8y/

клиентский HTML:

third party cookies are <span id="result"/>
<iframe src="https://mindmup.github.io/3rdpartycookiecheck/start.html"
    style="display:none" />

клиентская сторона JS:

 var receiveMessage = function (evt) {
   if (evt.data === 'MM:3PCunsupported') {
     document.getElementById('result').innerHTML = 'not supported';
   } else if (evt.data === 'MM:3PCsupported') {
     document.getElementById('result').innerHTML = 'supported';
   }
 };
 window.addEventListener("message", receiveMessage, false);

Конечно, для этого требуется, чтобы клиент выполнял JavaScript, что является недостатком по сравнению с решениями на базе сервера; С другой стороны, это проще, и вы спрашивали о решении JS.

Ответ 3

Alan solution отлично, но вам не нужно использовать PHP или любой другой язык программирования на стороне сервера.

По крайней мере, если вы используете nginx.:)

Это чистая * серверная конфигурация nginx для решения Alan:

Начало конфигурации Nginx

server {
    listen 80;
    server_name third-party.example.com

    # don't allow user browser to cache these replies
    expires -1;
    add_header Cache-Control "private";
    etag off;

Первый сторонний "файл JavaScript" - обслуживается nginx

    location = /step1.js.php {
        add_header Content-Type 'application/javascript; charset=UTF-8';

        add_header Set-Cookie "third_party_c_t=hey there!;Max-Age=172800";

        return 200 'window._3rd_party_test_step1_loaded();';
    }

Второй сторонний "файл JavaScript" - обслуживается nginx

    location = /step2.js.php {
        add_header Content-Type 'application/javascript; charset=UTF-8';

        set $test 'false';
        if ($cookie_third_party_c_t = 'hey there!') {
            set $test 'true';
            # clear the cookie
            add_header Set-Cookie "third_party_c_t=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
        }

        return 200 'window._3rd_party_test_step2_loaded($test);';
    }

Окончание конфигурации Nginx

}


Боковые заметки:

  • Да, да, я знаю, что IfIsEvil,
  • Я сохранил имена, заканчивающиеся на ".php" для полной совместимости с Alan "HTML test page" (third-party-cookies.html),
  • Вы также можете перемещать общую "настройку заголовка Content-Type" в обоих местах в раздел server (область) конфигурации - я сохранил его таким образом, чтобы сохранить его более "1:1".

Ответ 4

В теории вы бы просто вышли на страницу, где бы установили cookie третьей стороны, а затем проверьте наличие этого файла cookie. Тем не менее, стандартная защита браузера не позволяет сценариям из домена A делать что-либо с куки, установленными на доменах B, C и т.д., Например. вы не можете получить доступ к "чужим" файлам cookie.

Если у вас есть определенное использование, например проверка блокировки рекламы (которая также блокирует сторонний файл cookie отслеживания), вы можете проверить, находится ли контент рекламного сервера внутри страницы DOM, но вы не можете посмотрите, есть ли там файл cookie.

Ответ 5

  Обнаружение сторонних файлов cookie с использованием белого списка URL-адресов

Алан Х & Gojko Adzic достаточно хороши для большинства случаев использования, но эти решения не будут работать, если вы хотите, чтобы ваши пользователи создавали белый список файлов cookie третьих сторон только для определенных доменов.

Я представляю слегка измененную версию ответа Гойко Адзичаanswer

Для этого нам понадобятся два домена:

  • Домен 1, это страница, на которую попадает ваш пользователь, сначала она устанавливает tpc=pending, затем перенаправляет на Домен 2
  • Домен 2 вставляет URL-адрес домена 1 в iFrame, пытается установить cookie tpc=true и перенаправляет обратно в домен 1
  • Теперь домен 1 считывает файл cookie tpc и проверяет, является ли его true, если мы получаем значение true, сторонними cookie, если он все еще находится в pending, блокированные сторонние cookie заблокированы.

Теперь вы можете попросить своих пользователей внести в белый список (разрешить сторонние файлы cookie) ТОЛЬКО для Domain 1, также с помощью этого метода обнаружение третьей стороной будет accurate, если пользователи занесли в белый список ваш домен.


Это проверено в Chrome 74, 75, 76 & Край 78

К сожалению, Mozilla не предоставляет белый список URL-адресов, как в Chrome, и Safari имеет собственные механизмы обнаружения сторонних файлов cookie (ITP).

Постскриптум Выложу это демо в мой github, когда у меня будет время.