Rails 3, скрепка + S3 - Как сохранить экземпляр и защитить доступ

Это нормальный способ, если myObservableCollection не будет жить дольше, чем «this», и в этом случае вы можете получить утечку памяти, поскольку созданный за кадром делегат сохранит ссылку на ваш « это, которое будет поддерживать его. Если вы постоянно создаете и «уничтожаете» все, что слушает событие, вы обнаружите, что они не собираются сборщиком мусора.

Если это проблема, вы можете пойти по пути, предложенному в ответах, сохранив ссылку на обработчик, который вы должны сначала создать.

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

23
задан Nick Veys 6 March 2012 в 05:27
поделиться

3 ответа

На самом деле я только что реализовал авторизованные URL S3 в своем приложении Ruby on Rails 3 с помощью Paperclip . Позвольте мне рассказать, как я этого достиг.

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

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 и затем выполняете действие (например, загружаете ) в 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 . Таким образом, в основном через 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 .

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

54
ответ дан 29 November 2019 в 01:12
поделиться

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

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

Спецификации находятся в разделе «Потоков больше нет, время для перенаправления».

Краткое описание: S3 имеет четыре постоянные политики доступа, используя политику аутентифицированного чтения S3 обеспечивает способ создания аутентифицированного URL для частного контента, который работает только в течение определенного периода времени.

Я на самом деле не делал этого, поэтому, пожалуйста, дайте мне знать, если это работает для вас. : -)

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

5
ответ дан 29 November 2019 в 01:12
поделиться

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

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

1
ответ дан 29 November 2019 в 01:12
поделиться
Другие вопросы по тегам:

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