Это нормальный способ, если myObservableCollection не будет жить дольше, чем «this», и в этом случае вы можете получить утечку памяти, поскольку созданный за кадром делегат сохранит ссылку на ваш « это, которое будет поддерживать его. Если вы постоянно создаете и «уничтожаете» все, что слушает событие, вы обнаружите, что они не собираются сборщиком мусора.
Если это проблема, вы можете пойти по пути, предложенному в ответах, сохранив ссылку на обработчик, который вы должны сначала создать.
Другим решением является использование слабых ссылок для создания обработчика событий, который позволит собирать подписчика, если нет других ссылок. Я исследовал это решение в , этот вопрос и ответ .
На самом деле я только что реализовал авторизованные 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 .
Надеюсь, это поможет!
Вы можете попробовать то, что сказано на этой странице:
http://thewebfellas.com/blog/2009/8/29/protecting-your-paperclip-downloads
Спецификации находятся в разделе «Потоков больше нет, время для перенаправления».
Краткое описание: S3 имеет четыре постоянные политики доступа, используя политику аутентифицированного чтения S3 обеспечивает способ создания аутентифицированного URL для частного контента, который работает только в течение определенного периода времени.
Я на самом деле не делал этого, поэтому, пожалуйста, дайте мне знать, если это работает для вас. : -)
(сохранил мой ответ здесь: AWS S3 / Ruby on Rails / heroku: дыра в безопасности в моем приложении )
Самый простой способ сделать это, вероятно, сохранить файл со случайным, не угадываемым именем. Затем вы можете показать URL-адреса пользователям в экземпляре A, но пользователи экземпляра B не смогут их угадать.
Это не пуленепробиваемая безопасность, но она достаточно хороша. Facebook, например, использует этот подход для пользовательских фотографий.