Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Создание превьюшек изображений на лету с hash ключом. (Александр Эсаулов)
Author Message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Mon Jun 28, 2010 5:01 pm (написано за 18 минут 52 секунды)
   Post subject: Создание превьюшек изображений на лету с hash ключом.
Reply with quote

Возникла идея формировать превьшки на лету. Не знаю, как лучше делать, но пока придумал вот что.
Есть функция img() которая формирует урл к картинке, к примеру:
Code (html): скопировать код в буфер обмена
<img (december.com/html/4/element/img.html) src="<?=img('/upload/dir/image.jpg','max_w=150&max_w=150')?>" />
В итоге формируется примерно такой урл:
Code (any language): скопировать код в буфер обмена
/i/image.jpg?f=#закодированный_текст_с_параметрами#&cache=/admin/cache/images/36/fc/17/be/9910ee838b80
42239582d14d/b0980ec84d9babc8b73b008530760d87.jpg&hash=b385592f7e9b28fe1a496dbe8c2b1e3c
далее делаю в корне сайта такой .htaccess
Code (any language): скопировать код в буфер обмена
RewriteEngine on
RewriteCond %{QUERY_STRING} ^.*cache=(.*)&hash.*$
RewriteCond %{DOCUMENT_ROOT}%1 -f
RewriteCond %{DOCUMENT_ROOT}%1 -s
RewriteRule ^i/(.+)$ %1 [L]

RewriteCond %{REQUEST_URI} /i/.*?.*
RewriteRule ^i/(.+)$ /image.php [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule  ^(.+)$ index.php [L]
Что получается, при первом обращении к урлу запускается image.php, который проверяет параметры на соответствие ключу hash и если все нормально герерит картинку и выводит ее, а также записывает кэш по пути указанном в переменной $_GET['cache'];

При втором обращении к этому урлу mod_rewrite перенаправляет на реально созданную картинку, и при этом уже нет ни каких PHP процессов.

В этом примере мы сформировали урл изображения с максимальной шириной и высотой 150. Можно также передавать и другие параметры, например наложение на картинку. Хорошо тем, что в урле не фигурирует настоящий путь к файлу оригиналу. Все параметры передаются в зашифрованной переменной $_GET['f'].

Очень удобно пользоваться такой методикой, но вот меня беспокоит только одно, урлы получаются очень длинные, примерно 400-500 символов. Есть ли проблемы в браузерах с длиной такой? И у поисковых систем, когда images.yandex.ru и images.google.ru ищут по всей сети картинки, хотелось бы, чтобы они без проблем работали с такими урлами.

Подскажите, где костыли тут лежат.

P.S. пример урла:
Code (any language): скопировать код в буфер обмена
/i/1200.jpg?f=%2FEt9fnyvrciL%2B9p2oviY%2BchTO%2FeYzv8y0pxBTXZwX2wyu9ukvAWLz2puwOiLQ3s%2FJk%2FUByLJLoM%2F%2Bm
M0xQdNp%2FaHgTVwBJpSpzs1HS2Jx0OATW0lDoTua%2FerI6dF6wWc2w1Dk78JgIbWNlCAcP0FqW4UnonlIYoPGd7yVaIytXwADoEbvPOqL
B4%2FY08NJ1cVlh5Y6gTLaVNTm%2Bdz&cache=/admin/cache/images/36/fc/17/be/9910ee838b8042239582d14d/b0980
ec84d9babc8b73b008530760d87.jpg&hash=b385592f7e9b28fe1a496dbe8c2b1e3c
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Mon Jun 28, 2010 7:57 pm (спустя 2 часа 56 минут; написано за 3 минуты 4 секунды)
   Post subject:
Reply with quote

Александр Эсаулов wrote:
а также записывает кэш по пути указанном в переменной $_GET['cache'];
зачем от пользователя получать подобное? будто сервер сам не может определить, где ему хранить привьюхи.
Александр Эсаулов wrote:
При втором обращении к этому урлу mod_rewrite перенаправляет на реально созданную картинку
ссылки должны всегда формироваться на статику, а mod_rewrite при отсутствии файла переадресовывать на скрипт генерации. таким образом "длинных" урлов не будет вовсе. побочный момент этого, что в имени файла привьюхи нужно задавать как-то его размеры и т.п., то есть потенциально можно делать DDoS запрашивая картики с левыми размерами. Решается это достаточно просто ограничением запрашиваемых размеров и других параметров в скрипте генерации.
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Mon Jun 28, 2010 7:59 pm (спустя 2 минуты; написано за 1 минуту 39 секунд)
   Post subject:
Reply with quote

п.с. генерить превьюхи "на лету" имеет смысл если картинки массово добавляются администрацией. если же они добавляются пользоваьтелем, то скорее всего им же и будут запрошены, так что проще их генерить сразу при загрузке пользователем оригинала на сервер.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Mon Jun 28, 2010 9:44 pm (спустя 1 час 45 минут; написано за 11 минут 3 секунды)
   Post subject:
Reply with quote

dimagolov wrote:
п.с. генерить превьюхи "на лету" имеет смысл если картинки массово добавляются администрацией. если же они добавляются пользоваьтелем, то скорее всего им же и будут запрошены, так что проще их генерить сразу при загрузке пользователем оригинала на сервер.
Я категорически против создания превьюшек при загрузке картинок на сервер. Никогда нельзя точно знать, какие именно размеры могут потребоваться на выводе. Иногда требуется изменить дизайн сайта или что то переделать на выводе, и как быть в таком случае если картинок с подходящими размерами нет! Или нужно поменять наложение на фото, то тогда совсем засада. А по моему способу это можно делать с легкостью и без проблем. Раньше я пользовался конструкцией /images/img.jpg?w=200, та же схема, сначала РНР скрипт, потом статика, но тут действительно можно поменять вручную параметры и сгенерить на сервере ненужную картинку и сохранить ее кэш там. Этот метод я раньше использовал, а решил модернизировать и применить hash проверку введенных параметров. В придачу они еще и зашифрованы, в параметре $_GET['f'] и любое изменений урла приведет к несовпадению хеша, и будет ошибка 404. Вы наверное немного неправильно поняли методику. Конечно очень некрасивые урлы получаются, вот я и побаививаюсь немного, а может всетаки я неправильно делаю что то?
Back to top
View user's profile Send private message
Миша Спларов
Участник форума



Joined: 17 Nov 2003
Posts: 821
Карма: 65
   поощрить/наказать

Location: Россия, Москва

PostPosted: Tue Jun 29, 2010 5:51 am (спустя 8 часов 6 минут; написано за 16 секунд)
   Post subject:
Reply with quote

Quote:
но тут действительно можно поменять вручную параметры и сгенерить на сервере ненужную картинку и сохранить ее кэш там
Храните массив разрешённых размеров.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 10:54 am (спустя 5 часов 2 минуты; написано за 2 минуты 44 секунды)
   Post subject:
Reply with quote

Миша Спларов wrote:
Quote:
но тут действительно можно поменять вручную параметры и сгенерить на сервере ненужную картинку и сохранить ее кэш там
Храните массив разрешённых размеров.
Каким образом? Ну разрешу я параметры w,h,max_w,max_h, но их можно будет поменять значение через урл. Тут только с ключом безопасно можно делать. Это очень похоже на dklab.ru/lib/HTTP_UrlSigner/ Дмитрия Котерова, когда урл подписывается цифрой подписью.
Back to top
View user's profile Send private message
Миша Спларов
Участник форума



Joined: 17 Nov 2003
Posts: 821
Карма: 65
   поощрить/наказать

Location: Россия, Москва

PostPosted: Tue Jun 29, 2010 11:18 am (спустя 24 минуты; написано за 1 минуту 57 секунд)
   Post subject:
Reply with quote

Александр Эсаулов
Quote:
но их можно будет поменять значение через урл
Не понял этой фразы.
Почему указать массив небезопасно? Вредители смогут сгенерировать только картинки допустимых размеров (которые, в основном, и так будут в кэше от предыдущих запросов).
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 12:56 pm (спустя 1 час 37 минут; написано за 9 минут 8 секунд)
   Post subject:
Reply with quote

Миша Спларов wrote:
Александр Эсаулов
Quote:
но их можно будет поменять значение через урл
Не понял этой фразы.
Почему указать массив небезопасно? Вредители смогут сгенерировать только картинки допустимых размеров (которые, в основном, и так будут в кэше от предыдущих запросов).
Вот пример урла /images/img.jpg?w=200&h=150. Что здесь злоумышленнику ничего не мешает подставить свои значения, к примеру /images/img.jpg?w=250&h=100 и т.д. И при этом на сервере сгенерится кэш. А вот если будет что то вроде этого /images/img.jpg?w=200&h=150&hash=b385592f7e9b28fe1a496dbe8c2b1e3c, то уже подмена параметров исключена, т.к:
Code (php): скопировать код в буфер обмена
$SECRET='secret word';
$params=$_GET;
unset (www.php.net/unset)($params['hash']);
$calc_hash=md5 (www.php.net/md5)($SECRET.serialize($params));

if($_GET['hash']==$calc_hash)
{
 // то генерим картинку, выводим ее и сохраняем кэш
}
Соответственно как генерим урл к картинке тоже вычисляем hash. Здесь подмена параметров исключена! И не надо на сервере хранить массив.
Back to top
View user's profile Send private message
Миша Спларов
Участник форума



Joined: 17 Nov 2003
Posts: 821
Карма: 65
   поощрить/наказать

Location: Россия, Москва

PostPosted: Tue Jun 29, 2010 1:18 pm (спустя 22 минуты; написано за 1 минуту 46 секунд)
   Post subject:
Reply with quote

Вместо $SECRET = '...'; сделайте $allowedSizes = array('200x150',);
Потом проверка, что указанные в запросе ширина и высота в списке разрешённых.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 1:49 pm (спустя 31 минуту; написано за 5 минут 48 секунд)
   Post subject:
Reply with quote

Миша Спларов wrote:
Вместо $SECRET = '...'; сделайте $allowedSizes = array('200x150',);
Потом проверка, что указанные в запросе ширина и высота в списке разрешённых.
Каким образом? Вывожу к примеру я в шаблоне сайта картинку /images/img.jpg?w=200&h=150, и каким же образом я буду знать в /image.php который будет пережимать, что 200х150 это правильный допустимый размер? Предлагаете хранить все варианты сжимаемых размеров? Ну будет array('200x150','300x500','50х40') и Вы считаете, что так будет проще? Почему Вы отвергаете метод с цифровым подписыванием урла? Укажите хоть один недостаток моего и преимущества своего метода.
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Tue Jun 29, 2010 3:22 pm (спустя 1 час 32 минуты; написано за 4 минуты 44 секунды)
   Post subject:
Reply with quote

Александр Эсаулов wrote:
Укажите хоть один недостаток моего
Во-первых Бритва Оккама. Возможность контролировать допустимые для генерации размеры в скрипте генерации делает уникальный для каждой картинки хеш избыточным.

Кроме того, наличие хеша в ссылке на привьюху подразуммевает обязательный запуск скрипта для его проверки. А это удар по производительности. Если изначально иметь ссылки на статику (стандартные и предсказуемые), а при их отсутствии генерить запрошенное скриптом, то большинство запросов будет исполняться веб-сервером, без привлечения php.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 3:41 pm (спустя 18 минут; написано за 7 минут 51 секунду)
   Post subject:
Reply with quote

dimagolov wrote:
Кроме того, наличие хеша в ссылке на привьюху подразуммевает обязательный запуск скрипта для его проверки. А это удар по производительности.
Не будет удара по производительности, внимательней изучите .htaccess в первом посте. РНР скрипт будет запускаться один только первый раз, в остальные разы mod_rewrite перенаправит на реальный кэш и РНР скрипт не будет запускаться. Смотрите именно первый пост, схему реализованного урла.
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Tue Jun 29, 2010 4:31 pm (спустя 50 минут; написано за 3 минуты 51 секунду)
   Post subject:
Reply with quote

Александр Эсаулов wrote:
внимательней изучите .htaccess в первом посте
и что? если бы это была просто ссылка на статическую картинку с размером в имени результат был бы идентичный. а разницы между проверкой хешей или массив допустимых размеров я не вижу никакой, и то и другое делается скриптом для выяснения того можно или нет генерить такую картинку. только начилие хешей делает страшным URL не давая никаких заметных преимуществ.

но если религия не позволяет проверять размеры по массиву, то ничто не мешает добавить тот же хеш в имя статической картинки и разбирать скриптом именно его.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 6:16 pm (спустя 1 час 44 минуты; написано за 7 минут 42 секунды)
   Post subject:
Reply with quote

dimagolov wrote:
Александр Эсаулов wrote:
внимательней изучите .htaccess в первом посте
и что? если бы это была просто ссылка на статическую картинку с размером в имени результат был бы идентичный. а разницы между проверкой хешей или массив допустимых размеров я не вижу никакой, и то и другое делается скриптом для выяснения того можно или нет генерить такую картинку. только начилие хешей делает страшным URL не давая никаких заметных преимуществ.

но если религия не позволяет проверять размеры по массиву, то ничто не мешает добавить тот же хеш в имя статической картинки и разбирать скриптом именно его.
Да, тут я согласен с Вами. Религия действительно не позволяет содержать дополнительный массив с размерами, видимо без хеша не обойтись.
То что урлы получаются некрасивыми то да, только вот работать с этими урлами не человеку придется. Я еще в первом посте спросил, будут ли проблемы с такими урлами или нет, но никто ответа не дал. Кто нибудь может дать ответ, почему не стоит применять такие урлы? Некрасиво, но работает.
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Tue Jun 29, 2010 7:29 pm (спустя 1 час 13 минут; написано за 49 секунд)
   Post subject:
Reply with quote

Александр Эсаулов wrote:
Я еще в первом посте спросил, будут ли проблемы с такими урлами или нет
ну почитали бы в гуглотеке... (www.google.ru/search?source=ig&hl=ru&rlz=1G1GGLQ_RURU280&=&q=%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5+%D0%BD%D0%B0+%D0%B4%D0%BB%D0%B8%D0%BD%D1%83+url&aq=1&aqi=g3&aql=&oq=%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5+%D0%BD%D0%B0+%D0%B4%D0%BB%D0%B8%D0%BD%D1%83&gs_rfai=). Сразу первая ссылка искомая - paradigm.ru/2007/12/url-max-length
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Tue Jun 29, 2010 7:32 pm (спустя 3 минуты)
   Post subject:
Reply with quote

Александр Эсаулов wrote:
Кто нибудь может дать ответ, почему не стоит применять такие урлы? Некрасиво, но работает.
Потому что Бритва Оккама, KISS. Погуглите что это такое. Хотя я понимаю, что жалко расставаться с велосипедом, который сам построил, даже если у него квадратные колеса и ехать на нем не очень удобно.

п.с. а проблем можно указать множество. простейшая: такой урл просто вставленный в текст форума будет или обрезаться или рвать дизайн:

i/1200.jpg?f=%2FEt9fnyvrciL%2B9p2oviY%2BchTO%2FeYzv8y0pxBTXZwX2wyu9ukvAWLz2puwOiLQ3s%2FJk%2FUByLJLoM%2F%2BmM0xQdNp%2FaHgTVwBJpSpzs1HS2Jx0OATW0lDoTua%2FerI6dF6wWc2w1Dk78JgIbWNlCAcP0FqW4UnonlIYoPGd7yVaIytXwADoEbvPOqLB4%2FY08NJ1cVlh5Y6gTLaVNTm%2Bdz&cache=/admin/cache/images/36/fc/17/be/9910ee838b8042239582d14d/b0980ec84d9babc8b73b008530760d87.jpg&hash=b385592f7e9b28fe1a496dbe8c2b1e3c
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Wed Jun 30, 2010 10:37 am (спустя 15 часов 4 минуты; написано за 1 минуту 8 секунд)
   Post subject:
Reply with quote

Да, страница рвется. Хорошо, спасибо всем! Я еще подумаю как ужать урл к минимуму, как придумаю скажу.
Back to top
View user's profile Send private message
bæv
Модератор «Дзена»



Joined: 27 Aug 2003
Posts: 7275
Карма: 9985
   поощрить/наказать


PostPosted: Wed Jun 30, 2010 1:01 pm (спустя 2 часа 24 минуты; написано за 1 минуту 18 секунд)
   Post subject:
Reply with quote


М

Исправил заголовок темы — нет в русском языке такого слова как «ключем».
Лично мне — глаза режет.
Back to top
View user's profile Send private message
Александр Эсаулов
Участник форума



Joined: 16 Oct 2009
Posts: 38
Карма: 0
   поощрить/наказать


PostPosted: Wed Jun 30, 2010 2:21 pm (спустя 1 час 19 минут; написано за 3 минуты 13 секунд)
   Post subject:
Reply with quote

bæv wrote:
Исправил заголовок темы — нет в русском языке такого слова как «ключем».
Лично мне — глаза режет.
Спасибо, случайно наверное ошибся при создании темы. Хотя в самих постах писал правильно.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML