Rails 3, paperclip + S3 - Howto Store для экземпляра и защиты доступа - PullRequest
22 голосов
/ 10 октября 2010

У меня есть приложение Rails 3 со скрепкой, предназначенное для хранения данных на S3.

В приложении пользователи принадлежат экземпляру.

Я бы хотел, чтобы данные сохранялись по всем моделям в каждом случае. И хотел бы запретить пользователю доступ к экземпляру A или возможность загрузки данных из экземпляра B.

Какой лучший способ справиться с этим? спасибо

Ответы [ 3 ]

54 голосов
/ 31 октября 2010

Я на самом деле только что реализовал авторизованные URL S3 в моем Ruby on Rails 3 приложении с Скрепкой .Позвольте мне рассказать, как я это сделал.

Итак, то, что я сделал, и то, что вы, вероятно, хотите, довольно легко реализовать.Позвольте привести пример:

FileObject модель

has_attached_file :attachment,
  :path           => "files/:id/:basename.:extension",
  :storage        => :s3,
  :s3_permissions => :private,
  :s3_credentials => File.join(Rails.root, 'config', 's3.yml')

FileObjectsController контроллер

  def download
    @file_object = FileObject.find(params[:id])
    redirect_to(@file_object.attachment.expiring_url(10))
  end

Я верю в этоэто довольно просто.Вы добавляете вложение Paperclip в модель FileObject и затем выполняете действие (например, download ) в FileObjectsController .Таким образом, вы можете выполнить некоторую авторизацию на уровне приложения из вашего контроллера с помощью before_filter или чего-то еще.

Метод expiring_url () (предоставляется Paperclip ) на @file_object.attachment в основном запрашивает у Amazon S3 ключ, который делает файл доступным с этим конкретным ключом.Первый аргумент метода expiring_url () принимает целое число, представляющее сумму секунд , в которой вы хотите, чтобы срок действия предоставленного URL истек.

В моем приложении этов настоящее время установлено значение 10 (@file_object.attachment.expiring_url (10) ), поэтому, когда пользователь запрашивает файл, пользователь ВСЕГДА должен пройти через мое приложение, например myapp.com / file_objects / 3 / download , чтобы получить новый действительный URL-адрес от Amazon, который пользователь сразу же будет использовать для загрузки файла, поскольку мы используем метод redirect_to в download action.Таким образом, в основном через 10 секунд после того, как пользователь нажимает действие download , срок действия ссылки уже истек, и пользователь успешно (или все еще) успешно загружает файл, в то время как он остается защищенным от любых неавторизованных пользователей.

Я даже пытался установить expiring_url (1) , чтобы URL-адрес мгновенно истекал после того, как пользователь инициирует запрос Amazon S3 для URL-адреса.Это работало для меня локально, но никогда не использовало его в производстве, вы можете попробовать это тоже.Однако я установил его на 10 секунд, чтобы дать серверу короткий период времени для ответа.До сих пор отлично работает, и я сомневаюсь, что кто-нибудь перехватит чей-то URL-адрес в течение 10 секунд после его создания, не говоря уже о том, что это за URL.

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

has_attached_file :attachment,
  :path => "files/:id/:secret_key/:basename.:extension"

Так что каждый URL имеет свой уникальный secret_key в своем пути, что усложняет захват во времениURL доступен.Напоминаем, что, хотя URL-адрес вашего файла остается прежним, доступность зависит от дополнительных параметров, предоставляемых Amazon S3, срок действия которых истекает:

http://s3.amazonaws.com/mybucket/files/f5039a57acc187b36c2d/my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

Обратите внимание на эту часть, которая является ключом, который Amazon генерирует, и срок действия которого истекает.делает файл временно доступным:

my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

Вот и все.И это меняется с каждым запросом вашего файла, если он запрашивается с помощью действия download .

Надеюсь, это поможет!

5 голосов
/ 29 октября 2010

Вы можете попробовать то, что сказано на этой странице:

http://thewebfellas.com/blog/2009/8/29/protecting-your-paperclip-downloads

Спецификации находятся в разделе "Нет больше потоковой передачи, время для перенаправления".* Сводка: S3 имеет четыре постоянные политики доступа, используя политику аутентифицированного чтения S3 предоставляет способ генерирования аутентифицированного URL-адреса для частного контента, который работает только в течение определенного периода времени.* На самом деле я этого не делал, поэтому, пожалуйста, дайте мне знать, если это работает для вас.: -)

(сохранил мой ответ здесь: AWS S3 / Ruby on Rails / heroku: дыра в безопасности в моем приложении )

1 голос
/ 10 октября 2010

Самый простой способ сделать это, вероятно, сохранить файл со случайным, не угадываемым именем. Затем вы можете показать URL-адреса пользователям в экземпляре A, но пользователи экземпляра B не смогут их угадать.

Это не пуленепробиваемая безопасность, но она достаточно хороша. Например, Facebook использует этот подход для пользовательских фотографий.

...