Rails, Rackspace Cloud Files, Referrer ACL

Я использую Rackspace Cloud Files в качестве сервера хранения файлов для своего приложения. Файлы, загружаемые пользователями, должны быть авторизованы в моем приложении, после чего контроллер будет перенаправлять их на правильный URL-адрес CDN Rackspace Cloud Files. Я пытаюсь выполнить авторизацию, используя ACL Referrer Rackspace Cloud Files.

Итак, позвольте мне добавить очень простой фрагмент, чтобы прояснить, чего я пытаюсь достичь.

class FilesController < ApplicationController
  def download
    redirect_to(some_url_to_a_file_on_cloud_files_url)
  end
end

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

http://a-subdomain.domain.com/projects/:project_id/files/:file_id/download

Итак, с помощью драгоценного камня CloudFiles я настроил регулярное выражение ACL Referrer, которое должно работать.

http\:\/\/.+\.domain\.com\/projects\/\d+\/files\/\d+\/download

Когда пользователь щелкает ссылку в веб-интерфейсе, он перенаправляет его на указанный выше URL-адрес и, в зависимости от параметров, из действия загрузки перенаправляет пользователя на правильный URL-адрес файла Rackspace Cloud Files.

Что ж, я получаю сообщение об ошибке, говорящее о том, что я неавторизован (неверный http-реферер). У меня есть подозрение, что, поскольку я выполняю перенаправление из действия загрузки прямо в облачные файлы, это не «считается» HTTP-реферером, и вместо того, чтобы использовать этот URL-адрес в качестве реферера, я думаю, что он может использовать этот URL-адрес:

http\:\/\/.+\.domain\.com\/projects\/\d+\/files

Поскольку это страница, на которой вы находитесь, когда хотите щелкнуть ссылку «скачать», которая направляет пользователя к действию загрузки в FilesController.

Когда я устанавливаю HTTP Referrer для Rackspace ACL только так:

http\:\/\/.+\.domain\.com\/projects\/\d+\/files

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

Итак, я думаю, мой вопрос в том, кто-нибудь знает, как и почему то, что я пытаюсь сделать, не работает, и есть какие-либо предложения/идеи? Как я уже сказал, я думаю, что когда пользователь щелкает ссылку, реферер устанавливается на местоположение, по которому щелкают файл, а не на URL-адрес, по которому пользователь перенаправляется на фактический файл в облачных файлах.

Возможно ли что-то подобное?

class FilesController < ApplicationController
  def download
    # Dynamically set a HTTP Referrer here before
    # redirecting the user to the actual file on cloud files
    # so the user is authorized to download the file?
    redirect_to(some_url_to_a_file_on_cloud_files_url)
  end
end

Любая помощь и предложения приветствуются!

Спасибо!


person Michael van Rooijen    schedule 26.10.2010    source источник
comment
На самом деле я выбрал Amazon S3, а не Rackspace Cloud Files по нескольким причинам. Но то, что касается темы выше, заключается в том, что очень просто добавить авторизацию в Amazon S3 в Ruby on Rails с помощью драгоценного камня Paperclip. По сути, у вас есть частная корзина, и вы используете метод Paperclips expiring_url для создания уникального ключа для каждой загрузки и истечения срока его действия в течение нескольких секунд. Очень простое, быстрое и безопасное решение вышеуказанной проблемы. Таким образом, авторизация может быть выполнена на прикладном уровне.   -  person Michael van Rooijen    schedule 31.10.2010


Ответы (2)


Как правило, комментария Микаэля более чем достаточно, чтобы объяснить, почему S3 лидирует в этом вопросе, но если вы действительно хотите добавить некоторые специальные HTTP-заголовки в свой запрос Rackspace, сделайте собственный HTTP-запрос и извлеките файл вручную:

class DownloadsController < ApplicationController
   def download
     send_data HTTParty.get(some_url_to_a_file_on_cloud_files_url, :headers => {"x-special-headers" => "AWESOME" }), :file_name => "myfile.something"
   end
end

Да, вы можете написать этот пример лучше, но это общая идея.

person Elad Meidar    schedule 13.08.2012