Отображать контент только в том случае, если он загружен из кадра из определенных доменов?

Похоже, что большинство вопросов, касающихся обнаружения фреймов, задают люди, желающие предотвратить появление своего сайта внутри фрейма. Тем не менее, я пытаюсь найти способ запретить отображение определенной страницы php, если она не находится во фрейме. Одно предостережение заключается в том, что iframe и главная страница находятся в разных доменах.

domain1.com/index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Site/title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0">
        <meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
        <meta HTTP-EQUIV="Expires" CONTENT="-1">
    </head>
    <body>
        <div id="content">
            <iframe width="100%" height="100%" frameborder="0" src="http://domain2.com/browse.php" />   
        </div>
    </body>
</html>

Я попробовал следующее как способ проверки:

  • Посмотрите на информацию REFERER в domain2.com/browse.php, чтобы увидеть, была ли она передана из domain1.com/index.php. Это имело ограниченный успех, так как я записывал около 1000 посетителей в день с отключенной информацией о реферерах

  • Передача IP-адреса пользователя из domain1.com/index.php в domain2.com/browse.php как часть зашифрованной строки запроса. Это также имело ограниченный успех, но я думаю, что кэширование (несмотря на мои попытки его отключить) заставляло index.php передавать старую зашифрованную строку запроса в browse.php с устаревшим IP-адресом.

В идеале я хотел бы знать, если domain2.com/browse.php был загружен в domain1.com/index.php, но если это невозможно, я бы хотел, чтобы browse.php не отображал контент, если он не находится в IFrame.

Помощь очень ценится

2 ответа

Вы использовали тег PHP в своем вопросе. Почему бы не использовать PHP для включения внешней страницы:

<?php

// get doc from url
$doc = new DOMDocument;
$doc->loadhtmlfile('http://bitinfocharts.com/x11coin/');

function getElements($tagName,$stripTag = FALSE)
// echo all these elements in direct succession
{
  global $doc;
  $elements = $doc->getElementsByTagName($tagName);
  foreach ($elements as $node)
  {
    $html = $doc->savehtml($node);
    if ($stripTag)
    {
      $html = substr($html,strpos($html,'>')+1);
      $html = substr($html,0,strrpos($html,'<'));
    }
    echo $html;
  }
}

?><!doctype html>
<html lang=en>
    <head>
        <title>Site</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0">
        <meta HTTP-EQUIV="Pragma" CONTENT="no-cache">
        <meta HTTP-EQUIV="Expires" CONTENT="-1">
        <?php echo '        <base href="'.$url.'">'.PHP_EOL; ?>
        <?php echo '        '; getElements('link'); ?>
        <?php echo '        '; getElements('script'); ?>
        <?php echo '        '; getElements('style'); ?>
    </head>
    <body>
        <div id="content">
           <?php getElements('body',TRUE); ?>
        </div>
    </body>
</html>

Я не говорю, что это идеально, и при этом я не знаю, что это то, что вы хотите, но это хорошо скрывает внешний источник. Защитите его паролем, и никто не сможет его загрузить.

Вы настаиваете на использовании <iframe>, Что вы могли бы сделать, это получить внешний файл с помощью простого локального файла PHP с, как вы уже догадались, file_get_contents()и повторить это. Все, что вам нужно добавить к содержанию, это снова <base> тег. Что это помогает? Два момента:

  1. Теперь вы можете ограничить загрузку с вашего внешнего сервера только тем сервером, который вы хотите разрешить загружать.
  2. Этот сервер оказывается сервером, где ваш <iframe> страница есть. Вы можете проверить на этом сервере, прежде чем обслуживать содержимое <iframe> что они только что загрузили <iframe> стр.

Таким образом, вам не нужна связь между серверами для проверки загрузки. Убедитесь, что <iframe> страница не кэшируется!

(извините за столько правок, но этот редактор немного странный.)

Итак, моя идея - загрузить внешнюю страницу локально. Давайте назовем эту локальную страницу "МЕСТНОЙ". И давайте назовем страницу, на которую он будет загружен, в "IFRAME".

Вы ограничиваете загрузку своей внешней страницы на сервер, на котором находится LOCAL.

Самый простой способ проверить, авторизован ли пользователь видеть LOCAL, - использовать закодированные метки времени. Поэтому, когда IFRAME генерируется сервером, он просто помещает закодированную временную метку в URL LOCAL. Почему закодировано? Потому что это не должно быть слишком очевидно, что это такое, и вы должны иметь возможность декодировать его в LOCAL.

Итак, сначала способ сгенерировать метку времени кодирования:

$code = urlencode(gzencode(time()));

В LOCAL мы будем использовать противоположное:

$timestamp = gzdecode(urldecode($code)));

Пожалуйста, проверьте эти процедуры, urldecode() возможно, уже были применены на вашем сервере. Вы можете сделать эти процедуры кодирования и декодирования более сложными, если хотите, чтобы хакерам было сложнее угадать, что происходит.

Теперь в вашем файле LOCAL вам сначала нужно проверить, что полученная вами временная метка действительно является числом и не слишком старая:

if (is_numeric($timestamp)) $age = abs(time()-$timestamp); 
                       else $age = 99999999;

Например, вы можете разместить пустую страницу, если ее содержание старше 5 минут. Не забудьте установить <base> тег в LOCAL, вы можете использовать классы DOM для этого, как в моем предыдущем ответе. В качестве альтернативы вы можете сделать все относительные ссылки абсолютными.

У этой идеи есть один явный недостаток. Там могут быть JavaScript, которые основаны на том, что они работают на внешнем сервере. В этом случае они не, и это может сломать их.

(Почему я делаю так много опечаток?)

Другие вопросы по тегам