Защита от прямого скачивания для больших файлов

  • Автор темы Автор темы Илья2
  • Дата начала Дата начала
А почему бы не отдавать скрипту данные через GET? Создаешь в базе запись о закачке файла в которой будет описано что качать разрешено (это не принципиально, что хошь то и пиши) главное чтобы скрипт получив урл вытащил из него id закачки и поискал в базе, если нашёл-значит качать можно, не нашел : объект не найден.
 
Я работал над такой же задачей
Хочу поделиться проблемами и тем, как я их решил
1. Делать SetEnvIf - как то ненадежно - User-Agent, Referrer можно подменить (пришлось отказаться)
2. Делать скрипт читающий и выкидывающий в поток содержимое пробовал, Но. при скачке с https:// сайта в некоторых версиях IE был облом - файл или битый качался, либо портилось имя, либо IE терял файл в своем кэше (глупо но факт)
3. Давать открытый доступ - очевидно нехотелось

Сделал следующее:
Хранилище файлов расположил вне дерева сайта, дабы не лазали.
Сделал временное хранилище которое чищу find'ом по крону, удаля все что старее некоторого времени
Когда человек хочет скачать файл, создаю во временном хранилище каталог $name=md5(time()) в нем создаю ссылку на реальный файл и переправляю пользователя туда
Тут уже можно .htaccess'ом перекрыть некоторые вещи, но это уже на свой вкус.
 
Имхо, очень хорошая идея.

-~{}~ 01.07.04 17:25:

только лучше md5(microtime());
 
Доброго времени суток всем.
Передо мной вот похожая задача стоит.
Необходимо клиентам выдавать виртуальные url на закачку. Т.е. что б они не видели откуда скачивается файл. И реализовать ограничие по количеству скачиваний и времени действия "мнимой"ссылки

Пока возникли такие идеи:
Чтобы не показывать ссылку можно читать файл в браузер. Вообщем то, что обсуждалось выше.
А в сессии записывать время и линк на этот файл, поставить счётчик на количество скачиваний.

Может у кого есть более рациональное решение данного вопроса.
 
А ты сделай так: генериш случайный урл для данного клиента. Затем урл активируется при первой попытке скачат с него что нибудь и живёт эта ссылка к примеру 2 дня. В базе храниш её id и время активации с флагом активности и принадлежности пользователю (это чтоб потом ему не новую ссылку на тот-же файл генерить, а использовать старую). Когда ссылка перестаёт действовать она всё равно остаётся в базе на очень долгий срок чтобы срок давности её успел выйти (к примеру пол года). Ну а затем ссылку удаляешь из базы. Естесственно что файл клиенту отдаётся через скрипт.
 
Автор оригинала: feelsgood
Необходимо клиентам выдавать виртуальные url на закачку. Т.е. что б они не видели откуда скачивается файл.
А зачем им ссылки выдавать то? Посадить куку и дать линк на сам файл, а в папку поместить htaccess с обработчиком:
Action checkinfo "/check.php?"
AddHandler checkinfo .pdf .zip .mp3

Юзер ломится к файлу, и запускает обработчик, который читает куку и дальше определяет дать добро на закачку или нет. Так на оракл-сате реализовано и не надо файлы прятать.
 
проще накопать антилич скриптов и посмотреть как там делается
 
Dikobrazz
Юзер ломится к файлу, и запускает обработчик, который читает куку и дальше определяет дать добро на закачку или нет. Так на оракл-сате реализовано и не надо файлы прятать.
Хмм... А отдавать файл надо скриптом? Или мы передаем какое состояние апачу и он решает давать закачивать файл или нет?
 
Originally posted by gene_vbj

Сделал следующее:

Когда человек хочет скачать файл, создаю во временном хранилище каталог $name=md5(time()) в нем создаю ссылку на реальный файл и переправляю пользователя туда
Какого плана ссылочку ты создаешь?
ln -s ... ???

Originally posted by
Dikobrazz


Юзер ломится к файлу, и запускает обработчик, который читает куку и дальше определяет дать добро на закачку или нет. Так на оракл-сате реализовано и не надо файлы прятать.
Что обрабочтки возвращать должен: код ответа, или что-то еще?
 
Защита от прямого скачивания для больших файлов
Originally posted by Dikobrazz
Юзер ломится к файлу, и запускает обработчик, который читает куку ...
То есть я как больной должен буду качать сотни метров через бродилку. А wget и прочее объявляем ересью. Ну ладно, я куку в wgete выставлю, не вопрос. А бедный забитый забытый необразованный юзер?
 
Даун-лоад менеджеры. Или речь идет о полном списке мне известных?
 
che
Даун-лоад менеджеры. Или речь идет о полном списке мне известных?
Ну просто большинство известных мне умеют работать с куками взятыми из интеграции в браузер.

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

Кстати, бедные забитые и необразованные юзвери обычно юзают reget и ему подобных, и следовательно - читаем что я написал выше.

А совсем на крайняк можно передавать идентификатор сессии в URL.
 
Регет у меня пару раз вставал криво и с оперой не интегрировался. С ие в общем то нормально. Кроме того, систему я уже три раза как переставил, а опера прежняя, просто импортирую закладки. Со всеми вытекающими. в общем вариантов много. Не говоря уже о ненадежности самих кук. Мое мнение - вся инфа должна быть забита в url. Если инфы много - в базу, а в урл - ид. Но это мое мнение, и я его не навязываю.
>>Кстати, бедные забитые и необразованные юзвери обычно юзают reget и ему подобных, и следовательно - читаем что я написал выше.
Лично мной был забит не один юзер до состояния готовности юзать wget, правда с картинками. Мой случай не единичный.
>>Тем более есть ресурсы напрямую рассчитанные на то, что файлы берутся при помощи браузера
На них прям так и написано?
>>А совсем на крайняк можно передавать идентификатор сессии в URL
аминь! о чем речь и шла.
 
Я сделал по такому принципу, который указал desperado

У меня одна только проблема, когда нажимаю в броузере скачать с помощью FlashGet то он закачивает index.html, которого в принципе вообще не существует

ссылка на файл такого типа
http://domen/clients/download/15/
где 15 - id файла, написано с помощью модуля mod_rewrite.

когда же я просто скачиваю например Mozzilой, то он нормально качает и поддерживает докачку.
Может кто-то скажет почему не хавает файл FlashGet ?

-~{}~ 21.01.05 14:08:

Автор оригинала: D!!!
Я сделал по такому принципу, который указал desperado

У меня одна только проблема, когда нажимаю в броузере скачать с помощью FlashGet то он закачивает index.html, которого в принципе вообще не существует

ссылка на файл такого типа
http://domen/clients/download/15/
где 15 - id файла, написано с помощью модуля mod_rewrite.

когда же я просто скачиваю например Mozzilой, то он нормально качает и поддерживает докачку.
Может кто-то скажет почему не хавает файл FlashGet ?
И вообще в ИЕ огромный ГЛЮК:
если прервать закачку, то он у меня перестает одупляться, т.е. не ходит больше по ссылкам :) Такая вот штука MSIE :D
 
Для FlashGet если есть в конце слеш - то он считает что это каталог и все что вернется считает index.html - ведь имени файла нет.

Если ему отдать имя через Content-Disposition: attachment; filename=имя файла
то все нормально.
 
Автор оригинала: alexhemp
Для FlashGet если есть в конце слеш - то он считает что это каталог и все что вернется считает index.html - ведь имени файла нет.

Если ему отдать имя через Content-Disposition: attachment; filename=имя файла
то все нормально.
Неправда, я именно так и делаю, вот код:
PHP:
$resume = true;
$speed_limit = 10240;

$running_time = 0;
$begin_time = time();

set_time_limit( 300 );

$f = fopen( $file, 'rb' );
if ( !$f )
{
	header( 'location: '.$cfg['root'].'/clients/files/' );
	exit;
}

$file_size = filesize( $file );
$file_date = date( "D, d M Y H:i:s T", filemtime( $file ) );
$offset = 0;

if ( isset( $_SERVER["HTTP_RANGE"] ) )
{
	if ( preg_match("/bytes=(\d+)-/", $_SERVER["HTTP_RANGE"], $range ) && $resume == true )
	{
		header( "HTTP/1.1 206 Partial Content" );
		$offset = $file_size - intval($range[1]);
	}
	else 
	{
		header( "HTTP/1.1 200 OK" );
	}
}
else
{
	header( "HTTP/1.1 200 OK" );
}

$data_start	= $offset;
$data_end	= $file_size - 1;
$etag		= md5( $file . $file_size . $file_date );

fseek( $f, $data_start );

header( "Content-Disposition: attachment; filename=".basename( $file ) );
header( "Last-Modified: ".$file_date );
header( "ETag: \"".$etag."\"" );
if( $resume ) header( "Accept-Ranges: bytes" );
header( "Content-Length: ".( $file_size-$data_start ) );
header( "Content-Range: bytes ".$data_start."-".$data_end."/".$file_size );
header( "Content-type: application/octet-stream" );

while( !feof( $f ) && ( connection_status() == 0 ) )
{
	print fread( $f, $speed_limit );
	flush();
	sleep(1);
	$running_time = time() - $begin_time;
	if( $running_time > 240 )
	{
		set_time_limit(300);
		$begin_time = time();
	}
}
fclose( $f );
 
D!!!

Поробуй ссылки строить без слеша на конце. Может это баг такой во FlashGet.
 
Сверху