Защита изображений на сайте с помощью ImageKit

В этом руководстве мы рассмотрим, как Instagram ограничивает доступ к URL-адресам изображений. Мы применим этот способ, чтобы защитить свой сайт от копирования графического контента.

Как Instagram защищает изображения?

Попробуем скопировать URL-адрес изображения, опубликованного в Instagram, а затем изменить его.

Как Instagram защищает изображения?

Что мы видим:

  1. Размер изображения, указанный в URL, не может быть изменен.
  2. Любая другая часть URL не может быть изменена или удалена.

Instagram также устанавливают срок жизни URL-адресов. В этом руководстве мы повторим это поведение.

Что создаем?

  • Создадим небольшую галерею изображений.
  • Реализуем некоторые методы защиты изображений, которые мы видели в предыдущем примере.
  • Добавим на изображение водяной знак.
  • Ограничим доступ к оригинальному изображению в высоком разрешении.

Ресурсы

  1. Знание HTML.
  2. Базовые навыки работы с NodeJS.
  3. Бесплатная учетная запись ImageKit.io. ImageKit.io - это комплексное решение для оптимизации и управления изображениями. Оно позволяет изменять размер изображения, обрезать наносить водяные знаки и т.д.

Базовая настройка

Для демонстрации создадим фотогалерею на тему еды:

1. Получаем URL-адреса для изображений

Загрузим изображения в медиа библиотеку, которая поставляется вместе с ImageKit.io. Здесь мы получим URL-адрес для каждого изображения.

Получаем URL-адреса для изображений

Ниже приведен URL-адрес изображения, которое мы загрузили в медиа библиотеку ImageKit.io.

https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg

2. Создание HTML-разметки

Создадим HTML-код для размещения трех изображений.

Создание HTML-разметки

Затем установим для изображений размер 300 на 300 пикселей. ImageKit.io поможет в этом. Можно использовать основанные на URL-адресах параметры преобразования в реальном времени, чтобы изменить размер изображения.

<img src="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300" />

Также предоставим варианты изображения для экранов с высоким разрешением с помощью атрибута srcset в img  и преобразования dpr.

<html>
<head>
    <title>My Food Gallery Page</title>
</head>
<body>
    <h1>My Food Gallery</h1>
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300" 
        srcset="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300, 
            https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,dpr-2 2x" 
    />
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300"
        srcset="https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300, 
            https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300,dpr-2 2x" 
    />
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300" 
        srcset="https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300, 
            https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300,dpr-2 2x" 
    />
</body>
</html>

Защита изображений

Приступаем к реализации защиты изображений.

1. Водяной знак для изображения

Одним из способов защиты изображений является нанесение на них водяных знаков. Логотип водяного знака мы загрузили в библиотеку ImageKit.

Водяной знак для изображения

Этот логотип доступен по следующему адресу:

https://ik.imagekit.io/demo/img/scotch_security/secure_cr21l_7GU.png

Для нанесения водяных знаков на изображения используем инструмент ImageKit. Теперь URL-адрес нашего изображения выглядит следующим образом:

<img src="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg
        ?tr=w-300,h-300
        ,oi-@@scotch_security@@secure_cr21l_7GU.png
        ,ofo-bottom_right
        ,ow-150" />

Само изображение теперь выглядит так.

Водяной знак для изображения - 2

Добавление водяного знака гарантирует, что никто не сможет использовать ваше изображение на своем сайте.

2. Предотвращение изменения URL-адреса или удаления водяного знака

Но ведь можно посмотреть URL-адрес, удалить параметры наложения водяного знака и получить изображение. То же самое относится и к любому другому параметру в URL-адресе.

Предотвращение изменения URL-адреса или удаления водяного знака

Исправим это.

Часть а. Генерация «подписанного» URL-адреса

Подпишем URL-адрес изображения с помощью хеш-кода, созданного с помощью алгоритма SHA1и секретного ключа, который известен только клиенту и серверу (клиент – это мы, а сервер изображений – ImageKit).

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

Если подписи совпадают, запрос обрабатывается. Если нет, то URL-адрес или подпись были подделаны и выполнение запроса блокируется.

В ImageKit создать подписанный URL-адрес довольно просто. Для этого применяется один из предоставляемых SDK. В примере ниже мы используем SDK NodeJS.

/__
    Будет выполнено на сервере NodeJS
__/
var imagekit = new ImageKit({
    privateKey : "our_private_key", // это основной параметр, необходимый для генерации подписи ...
});

var signedURL = imagekit.url({
    src : "https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150",
    signed : true   // этот параметр помогает в создании подписанного URL
});

Подписанный URL-адрес, созданный с помощью SDK, выглядит следующим образом:

https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=b19a8d348746e1e7f89a8c0262507ce36ad41a3d

В конце URL-адреса есть дополнительный параметр ik-s.

Для простоты мы генерируем подпись и заменяем существующий URL-адрес в HTML новым подписанным URL-адресом. В реальных условиях сервер использует шаблон для генерации HTML. Таким образом, именно сервер генерирует подписанные URL-адреса и использует их в тегах img.

Часть б. Ограничение доступа к неподписанному URL-адресу изображения

Также необходимо, чтобы сервер изображений, не отвечал запросы изображений, к которым не будет прикреплена действительная подпись. Для этого ImageKit использует параметр, который блокирует любые неподписанные запросы.

Часть б. Ограничение доступа к неподписанному URL-адресу изображения

Результат после генерации подписи

Вот так выглядит HTML с новыми подписанными URL-адресами изображений.

<html>
<head>
    <title>My Food Gallery Page</title>
</head>
<body>
    <h1>My Food Gallery</h1>
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=7cf746087e01ed1d3ad58ca64156745070e69e3e" 

        srcset="https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=7cf746087e01ed1d3ad58ca64156745070e69e3e,

            https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300,dpr-2,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=02bd8e66a0000dbdb73619211743c8f6fa5addf0 2x" 
    />
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=1bbab2b2fc63abdaf585197b1d9707220cc07b6c"

        srcset="https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=1bbab2b2fc63abdaf585197b1d9707220cc07b6c, 

            https://ik.imagekit.io/demo/img/scotch_security/2_fGwKLAgUUd.jpeg?tr=w-300,h-300,dpr-2,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=9030030923deada4531f619e033660ba510499d6 2x" 
    />
    <img 
        src="https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=ec65c1f6354de6bb4e16d2ae3bb13b3828f9816e" 

        srcset="https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=ec65c1f6354de6bb4e16d2ae3bb13b3828f9816e, 

            https://ik.imagekit.io/demo/img/scotch_security/3_xqMQs0ib3.jpeg?tr=w-300,h-300,dpr-2,oi-@@scotch_security@@secure_cr21l_7GU.png,ofo-bottom_right,ow-150&ik-s=b71bc7d5e9d0e11b8af5c1250ec50ae546e165ad 2x" 
    />
</body>
</html>

Использование не подписанного URL-адреса теперь приведет к ошибке. Подобное мы видели в Instagram.

Теперь никто не может удалить водяной знак с изображения или скачать его в другой размерности.

Результат после генерации подписи

Предоставление доступа к оригинальному изображению платным пользователям

На данном этапе реализации невозможно получить исходное изображение с URL-адреса. Учетная запись ImageKit настроена на доставку только тех изображений, к которым прикреплена подпись.

Предоставление доступа к оригинальному изображению платным пользователям

Также нужно убедиться, что срок действия URL-адреса истекает через один час. Для этого мы передаем в исходном коде другой параметр, указывающий количество секунд до истечения срока действия URL-адреса.

var signedURL = imagekit.url({
    src : "https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg?tr=w-300,h-300",
    signed : true   // этот параметр помогает в создании подписанного URL
    expireSeconds : 3600 // количество секунд до окончания срока действия URL 
});

Это дает нам следующий URL-адрес:

https://ik.imagekit.io/demo/img/scotch_security/1_GTMtFxEf5.jpeg
    ?tr=w-300,h-300
    &ik-s=f65fd8e3136b557e61dc69c2ed19182f07a1ce5
    &ik-t=1234567890

В приведенном выше URL используется дополнительный параметр запроса ik-t, который является временной меткой.

Настройка параметров подписи для конкретного изображения, а не для всей учетной записи

В ImageKit доступна функция, позволяющая наложить ограничение на неподписанные URL-адреса, относящиеся к конкретному изображению, а не ко всей учетной записи.

Она  называется приватные изображения. Мы можем пометить изображение как «приватное», когда загружаем его в библиотеку ImageKit. Доступ к такому изображению возможен только через подписанные URL-адреса, даже если настройка использования подписанных URL отключена.

Заключение

ImageKit упрощает реализацию защиты изображений. Такие сервисы, как Instagram, уже используют подобные инструменты для URL-адресов изображений. Реализуйте это для своих изображений с помощью ImageKit.

Вадим Дворниковавтор-переводчик статьи «Securing website images the Instagram way using ImageKit»

Пожалуйста, оставляйте ваши комментарии по текущей теме статьи. Мы очень благодарим вас за ваши комментарии, лайки, дизлайки, подписки, отклики!