Подтвердить что ты не робот

Разрешение пользователю загружать файл из хранилища S3

Сейчас я использую Amazon S3 и Paperclip, который позволяет моим пользователям загружать изображение, связанное с создаваемым им событием. Моя конечная цель состоит в том, что другие могут просмотреть это событие, чтобы иметь возможность щелкнуть изображение и заставить его запросить СОХРАНИТЬ на свой компьютер. На данный момент щелчок по ссылке откроет изображение в окне браузера. Я скорее попрошу их скачать вместо этого. Все изображения сохраняются только на S3, а не локально. Необходимо скрыть открытый s3-url, если это возможно, или замаскировать его

Вот моя текущая настройка

Index.html

<%= link_to 'Download Creative', event.creative.url, class: "btn btn-info" %>

Event.rb

has_attached_file :creative,
                :styles => { :thumb => "150x150", :custcreative => "250x75" },
                :path => ":attachment/:id/:style.:extension",
                :s3_domain_url => "******.s3.amazonaws.com",
                :storage => :s3,
                :s3_credentials => Rails.root.join("config/s3.yml"),
                :bucket => '*****',
                :s3_permissions => :public_read,
                :s3_protocol => "http",
                :convert_options => { :all => "-auto-orient" },
                :encode => 'utf8'

Надеюсь, кто-то может мне помочь.

4b9b3361

Ответ 1

Чтобы сделать эту работу, я только что добавил новое действие в контроллер, поэтому в вашем случае это может быть:

#routes
resources :events do
  member { get :download }
end

#index
<%= link_to 'Download Creative', download_event_path(event), class: "btn btn-info" %>

#events_controller
def download
  data = open(event.creative_url)
  send_data data.read, :type => data.content_type, :x_sendfile => true
end

EDIT: правильное решение для действия контроллера загрузки можно найти здесь (я обновил код выше): Заставить ссылку для загрузки MP3, а не проигрывать его?

Ответ 2

Чтобы избежать дополнительной загрузки вашего приложения (сохранение динамического времени в Heroku), я бы скорее сделал что-то вроде этого: добавьте этот метод в свою модель с приложением:

def download_url(style_name=:original)
  creative.s3_bucket.objects[creative.s3_object(style_name).key].url_for(:read,
      :secure => true,
      :expires => 24*3600,  # 24 hours
      :response_content_disposition => "attachment; filename='#{creative_file_name}'").to_s
end

И затем используйте его в своих представлениях/контроллерах, например:

<%= link_to 'Download Creative', event.download_url, class: "btn btn-info" %>

Ответ 3

Теперь в aws-sdk v2 существует метод: presigned_url, определенный в Aws:: S3:: Object, вы можете использовать этот метод для создания прямого URL-адреса загрузки для объекта s3:

s3 = Aws::S3::Resource.new
# YOUR-OBJECT-KEY should be the relative path of the object like 'uploads/user/logo/123/pic.png'
obj = s3.bucket('YOUR-BUCKET-NAME').object('YOUR-OBJECT-KEY')
url = obj.presigned_url(:get, expires_in: 3600, response_content_disposition: "attachment; filename='FILENAME'")

то в ваших представлениях просто используйте:

= link_to 'download', url

Ответ 4

event = Event.find(params[:id])
  data = open(event.creative.url)
  send_data data.read, :type => data.content_type, :x_sendfile => true, :url_based_filename => true
end

Ответ 5

Вам нужно установить " Content-Disposition" в " вложение" в заголовке ответа HTTP. Я не разработчик Rails - так что просто Google, и вы увидите много примеров, но это, вероятно, выглядит примерно так:

    :content_disposition => "attachment"

или

     ...
    :disposition => "attachment"