Как стать автором
Обновить

Защита картинок от копирования без «водяных знаков» — защита от дурака

Время на прочтение 3 мин
Количество просмотров 9.7K
Большинство веб-программистов рано или поздно сталкивается с вопросом защиты изображений от копирования для последующего распространения. Обычно, это решается при помощи GD — лепкой на нужные картинки большой прозрачной надписи типа «www.%sitename%.ru» или сильным уменьшением качества изображения, реже — блокировкой контекстного меню, ещё реже — клавиши Ctrl.

В своё время, когда у меня встал подобный вопрос, но варианты «водяные знаки» или «ухудшение качества» были неприемлемы, я заморочился и придумал кое-какое решение. Это, конечно, не панацея (кому надо — тот всё равно утянет), но в качестве «защиты от дурака» справляется на ура.

Кому интересно, добро пожаловать под кат.

Чтобы не быть голословным, сразу приведу пример, который потом буду подробно разбирать: пример

Сразу оговорюсь: к сожалению, не спасает, если в Safari сохранить страницу, как web-архив.

Разбор полётов


JS
Блокируем контекстное меню и клавишу Ctrl:
document.oncontextmenu = new Function("return false"); // блокируем контекстное меню

$(window).keypress(function(event){blockKey(event);}); // вызов функции блокировки клавиш
$(document).keypress(function(event){blockKey(event);}); // вызов функции блокировки клавиш
    
function blockKey(event){
    keyCode = event.keyCode;
    if (keyCode == '155'){ // не работает, т.к. PrintScreen является функцией заложенной в ОС, а не в браузер - до неё мы достучаться не сможем
        alert('printscreen');
        }
    if (keyCode == '17'){ // блокировка Ctrl
        alert('Блокировка включена.');
        }
    }


*для удобства, я почти всегда использую jQuery.

HTML
Говорим браузеру, что кэшировать ничего не нужно, а актуальность контента закончилась в прошлом веке:
<meta http-equiv="Expires" content="Fri, Jan 01 1997 05:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">


Картинку, которую хотим защитить, мы выводим, как бэкграунд div'а, внутри которого вставляем тэг img с прозрачной картинкой 1х1 пиксель:
<div style="width: 1000px; height: 70px; background:url(index.php?showImg=84f5452a1fb1625ba0e251646049a60a) no-repeat;">
    <img src="fail.gif" alt="" style="width: 1000px; height: 70px;" oncontextmenu="return false;">
</div>



PHP
Думаю, что вы заметили параметр «showImg=84f5452a1fb1625ba0e251646049a60a», который передается в наш индекс файл. Обратимся к php-коду, чтобы понять, как он формируется и для чего он нужен:
<?php
session_start();

if (!$_GET['showImg']){ // выполняем при загрузке страницы
    $_SESSION['imageId'] = md5(date('y-m-d H:i:s').rand()); // случайный хэш который присваиваем сессии
    
    Header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //Дата в прошлом 
    Header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 
    Header("Pragma: no-cache"); // HTTP/1.1 
    Header("Last-Modified: ".gmdate("D, d M Y H:i:s")."GMT"); // до кучи
?>

// ... наш html-код

<?php
    }

if ($_GET['showImg']){ // выполняем в ответ на запрос браузера "хочу картинку для бэкграунда"
    include_once('./hana_kartinke.php');
    echo hana($_GET['showImg']);
    }
?>


Содержимое скрипта «hana_kartinke.php»:
<?php
session_start();

function hana($code){
    if ($code == $_SESSION['imageId']){ // если запрос соответствует случайной сессии
        session_destroy(); // убиваем сессию
        $_SESSION['imageId'] = 'fail'; // и присваиваем ей левое значение
        $assa = file_get_contents('./habr.jpg'); // пихаем в переменную всё содержимое картинки, которую хотим защитить
        }else{
            $assa = 'Epic fail! =)'; // если запрос не соответствует сессии, пишем юзеру сообщение
            }
    
    return $assa; // возвращаем полученные данные в браузер юзера
    }
?>



Результат


Пользователь видит картинку, но не может её сохранить ни при помощи контекстного меню (оно заблокировано), ни копипастом (блок на Ctrl), ни как Файл\Сохранить страницу, а при попытке посмотреть картинку перейдя по ссылке из исходников html, он увидит многозначительную надпись «Epic fail! =)».

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

Надеюсь, что кому-то эта информация будет полезна.

UPD
Повторюсь — это не панацея, это — защита от дурака.

UPD 2
Для критиков и минусующих, хочу пояснить суть: я долгое время проработал в маркетинге и занимался программированием онлайн-опросов, а в мире маркетинга существует одна авторитетная организация — ESOMAR, в требования которой (касательно онлайн-опросов) входит пункт по защите контента (картинки, видео и т.п.) от сохранения пользователями, при этом, визуально этого заметно быть не должно (т.е. никаких водяных знаков и урезаний качества).

Понятно, что защитить что-либо в интернете невозможно (особенно, если оно УЖЕ попало к конечному пользователю — тот же кэш), но данные требования никто не отменял и пришлось как-то выкручиваться. В статье как раз и описан вариант решения подобной ситуации.
Теги:
Хабы:
+4
Комментарии 74
Комментарии Комментарии 74

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн