Как хранить частные фотографии и видео в Ruby on Rails - PullRequest
5 голосов
/ 02 мая 2010

Вот история:

  • Пользователь А должен иметь возможность загрузить изображение.
  • Пользователь А должен иметь возможность установить конфиденциальность. («Публичный» или «Частный»).
  • Пользователь B не должен иметь доступ к "личным" изображениям пользователя A.

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

Если я сохраню изображения в «RAILS_ROOT / public / images», любой, кто сможет угадать имя файла, может получить доступ к файлам. (например, доступ к http://example.com/public/images/uploads/john/family.png)

Мне нужно показать изображения с помощью тегов img, поэтому я не могу разместить файл, кроме public.

Как я могу гарантировать, что изображения пользователя или группы недоступны для других?

(Если я не могу добиться этого с помощью Paperclip, что является хорошим решением?)

Ответы [ 4 ]

8 голосов
/ 02 мая 2010

Вы можете заставить свой сервер rails выводить содержимое файлов изображений. Это делается с помощью действия контроллера (большинство действий печатает HTML, но это, например, JPG).

Тогда вы можете использовать свою систему авторизации для ограничения доступа на уровне контроллера !

class ImagesController
  #Default show Image method streams the file contents.
  #File doesn't have to be in public/ dir
  def show
    send_file @image.filename, :type => @image.content_type,
              :disposition => 'inline'
  end

  # Use your favorite authorization system to restrict access
  filter_access_to :show, :require => :view, :attribute_check => :true
end

В HTML-коде вы можете использовать:

<img src="/images/show/5" />
4 голосов
/ 02 мая 2010

Вот как я это сделал в аналогичном приложении.

  • Храните ваши изображения в Amazon S3 вместо локальной файловой системы. Скрепка поддерживает это.
  • Установите ваши: s3_permissions на "private" в настройках Paperclip
  • В вашей модели Image определите метод, который позволит вам выводить авторизованный, ограниченный по времени URL для изображения.

Шахта выглядит так:

def s3_url(style = :original, time_limit = 30.minutes)
  self.attachment.s3.interface.get_link(attachment.s3_bucket.to_s, attachment.path(style), time_limit)
end
  • После этого вы можете показывать изображения людям только в том случае, если у них есть разрешение на их просмотр (используйте то, что вам нравится), и вам не нужно беспокоиться о том, что люди угадывают / просматривают личные изображения. Он также не позволяет им передавать URL-адреса, поскольку срок их действия истекает (в URL-адресе есть токен).
  • Имейте в виду, что вашему приложению требуется время для создания авторизованных URL-адресов для каждого изображения. Итак, если у вас есть несколько изображений на странице, это повлияет на время загрузки.
4 голосов
/ 02 мая 2010

Я бы хотел, чтобы Paperclip использовал S3 на бэкэнде, установил для загруженных файлов конфиденциальные данные, а затем использовал «Альтернатива аутентификации запроса строки запроса» для создания URL-адресов для моих тегов изображения.

http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

1 голос
/ 18 октября 2012

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

Одна вещь, которую я хотел добавить, это то, что вы должны просмотреть это руководство для настройки X-Sendfile, которое позволит вашему приложению сообщить веб-серверу, что нужно обрабатывать отправку файлов. При таком подходе вы увидите гораздо лучшую производительность.

...