@sanya164

Возможно ли защитить сайт от скачивания файлов с других ресурсов?

Например у меня есть сайт, на нем есть файл .txt или .exe или .ipa
Возможно ли сделать так, что не могли люди использовать ссылку на мой файл на своем ресурсе?
Например файл лежит тут https://site.ru/prog.exe
Можно сделать так, что если люди заходят по этой ссылке не с моего сайта, а с другого, файл или не скачивался или их переносило на главную страницу моего сайта?
  • Вопрос задан
  • 6561 просмотр
Пригласить эксперта
Ответы на вопрос 2
kompi
@kompi
nullstack devoops
nginx
location ~ .(gif|png|jpe?g)$ {
     valid_referers none blocked mywebsite.com *.mywebsite.com;
     if ($invalid_referer) {
        return   403;
    }
}
Ответ написан
soprun
@soprun
Software Architecture
Так как "парсеры" других ресурсов читают html, можно сделать добавление ссылки через javascript ( имею в веду на страницу ссылка будет вставляться в определенный элемент).

Так же создать простую систему токенов.

Например у вас есть папка где лежат Ваши файлы "site.com/myfile/", все запросы к данной папки будут перенаправляться на файл обработки, где и будет проверяться "токен"..

Ссылка будет выглядеть так:
site.com/myfile/prog.exe?token=1234567890

GET параметр "token" сравниваем с тем что будет в сессии пользователя, если все хорошо от открываем файл, если нету то и скачать нельзя...

Как правило парсеры не хранят сессии и не смогут скачать файл...

-------- Решение:

Давайте с начало определимся с видом ссылки на файл.

Можно сделать так:
/myfile/img.jpg?b31598b111cf1c175e956830b764e3f1e6d0a364
или вот так:
/myfile/img.jpg?token=b31598b111cf1c175e956830b764e3f1e6d0a364

Мне более симпатичен первый вариант.

1. Необходимо в конфигурационном файле сервера сделать что бы все запросы по определенной папки открывали файл проверки.

Например download.php
По настройки для вашего веб сервера можно найти примеры водяного знака для изображений.
Принцип точно такой же.

Настройка .htaccess
<FilesMatch "\.(gif|jpg|jpeg|png)$">
   RewriteEngine On
   RewriteCond %{REQUEST_FILENAME} -f
   RewriteRule ^(.*)$ /download.php?file=$1 [T=application/x-httpd-php,L,QSA]
</FilesMatch>


2. Необходимо создать сессию и ключ.
session_name('session');
session_start();

define('token', "?" . hash('sha1', session_id() , false));
# define('token', "?token=" . hash('sha1', session_id() , false));


Придется добавить в ваши шаблоны константу "token" в конец ссылки.

3. Проверка ключа download.php

<?php

session_name('session');
session_start();

# if( !empty($_GET['token']) && $_GET['token'] == hash('sha1', session_id() , false) )

if (isset($_GET[hash('sha1', session_id(), false)])) {
    if (ob_get_level()) {
        ob_end_clean();
    }

    # $file = $_SERVER['DOCUMENT_ROOT'] . '/' . preg_replace('/%2F/', '/', urlencode(trim(preg_replace('%\?.*%i', null, $_SERVER['REQUEST_URI']), '/')));
    $file = $_GET['file'];

    if (!is_file($file)) exit("Файл не найден!");

    // заставляем браузер показать окно сохранения файла
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename=' . basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));

    // читаем файл и отправляем его пользователю
    readfile($file);
    exit;

} else exit("Неверный ключ авторизации");


Более короткий вариант:
<?php

session_name('session');
session_start();

if (!isset($_GET[hash('sha1', session_id(), false)])) exit("Неверный ключ авторизации");

if (ob_get_level()) ob_end_clean();

if (!(!empty($file = $_GET['file']) && is_file($file))) exit("Файл не найден!");

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));

exit (readfile($file));
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы