Отображать контент только в том случае, если он загружен из кадра из определенных доменов?
Похоже, что большинство вопросов, касающихся обнаружения фреймов, задают люди, желающие предотвратить появление своего сайта внутри фрейма. Тем не менее, я пытаюсь найти способ запретить отображение определенной страницы 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>
тег. Что это помогает? Два момента:
- Теперь вы можете ограничить загрузку с вашего внешнего сервера только тем сервером, который вы хотите разрешить загружать.
- Этот сервер оказывается сервером, где ваш
<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, которые основаны на том, что они работают на внешнем сервере. В этом случае они не, и это может сломать их.
(Почему я делаю так много опечаток?)