Как реализовать хранение картинок от пользователя на сервере?

Интересует подход с точки зрения безопасности и производительности.
Сначала решил это сделать как в ВК, чтобы адрес картинки был типо:
"example.com/c637820/v637821842/115d2/imageName.jpg"
Интересует здесь, что обозначает именно
1. c637820
2. v637821842
Откуда эти id?
Также очень понравилась реализация на Facebook,
там вообще доступ по определенному токену в get параметре у картинке:
"example.com/v/t1.0-9/283048_103813746439563_31482813_n.jpg?oh=63f4724d166e6e322316283885f15ddc&oe=58D3C4F4"

Получается, что в картинках есть доступ программному коду, что не безопасно.
  • Вопрос задан
  • 320 просмотров
Пригласить эксперта
Ответы на вопрос 3
dimonchik2013
@dimonchik2013
non progredi est regredi
отсюда
если не в той статье, то точно на сайте есть общий принцип - md5 и распределение по папкам

а если ВК хочешь спалить - то да, последние три цифры совпадают с цифрами в ИД
Ответ написан
Комментировать
T_y_l_e_r
@T_y_l_e_r
Исчерпывающий ответ
bablogon.net/view.php?p=151

В социальных сетях файлы разбросаны по разным серверам да еще привязаны к определенному id, поэтому их принцип хранения отличается от односерверной реализации
Ответ написан
zoonman
@zoonman
⋆⋆⋆⋆⋆
Получается, что в картинках есть доступ программному коду, что не безопасно.

В картинках нет доступ к программному коду. Это абсолютный бред.

Что же на самом деле происходит?
Для этого нужно понимать, как работает современная архитектура.

Когда вы запрашиваете картинку, то ваш запрос отправляется на балансировщики (да, их может быть несколько), для выбора ближайшего используется протокол anycast.
Далее балансировщик выбирает ближайший наименее загруженный веб-сервер.
Веб-сервер принимает запрос и разбирает его на компоненты.

Например в вышеприведенном примере, можно увидеть, что запрос выглядит примерно так
"scontent-lga3-1.xx.fbcdn.net/v/t1.0-9/283048_103813746439563_31482813_n.jpg?oh=63f4724d166e6e322316283885f15ddc&oe=58D3C4F4"

scontent-lga3-1 - имя хоста, на котором может храниться изображение. Этот хост является частью сети доставки контента.
v/t1.0-9 - понятно, что это версия, скорее всего версия варианта хранения. Facebook непрерывно развивается, поэтому наверняка имеется процедура миграции между различными версиями хранения данных.

283048_103813746439563_31482813 - уникальный идентификатор изображения, три части которого являются разного рода идентификаторами.
oh - скорее всего object hash - некая цифровая подпись объекта.
oe - object expiration - фейсбучный аналог e-tag, специальный параметр указывающий на устаревание объекта.

Если интересно, как работает хранилище фоток в Фейсбук можете почитать в их блоге https://code.facebook.com/posts/685565858139515/ne...

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

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

Итак, с точки зрения производительности, самое напряжное - скорость чтения данных с диска, т.е. обычное I/O, поэтому если вам нужна именно скорость, то надо сфокусироваться на быстром хранилище, т.е. SSD просто обязательно.

Далее нужны соображения по поводу надежности, балансировки, обеспечения безопасности доступа.
Вам нужно понять, что мир не заканчивается на уровне Apache и PHP. Например может быть свой особый модуль для nginx, который будет ходить в базу и проверять доступность объекта и лишь затем считывать его с диска. Т.е. то, что вы видите в адресной строке может не иметь ничего общего с тем, как эти данные фактически хранятся на диске, например они могут лежать в HDFS или GridFS.

В вашем случае с учетом вашего уровня знаний лучше всего воспользоваться проверенными решениями вроде хранения картинок в S3 и отдачи их через Cloudflare c кэшированием, например так
https://habrahabr.ru/post/245165/
или так https://habrahabr.ru/company/io/blog/257533/
Ответ написан
Ваш ответ на вопрос

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

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