Ruby on Rails和AWS S3即将过期下载链接

时间:2018-01-03 19:04:16

标签: ruby-on-rails amazon-s3

我是编码的新手,我希望我能正确解释这个问题。像大多数人一样,我开始使用Ruby on Rails。

我正在尝试从AWS S3请求网址传递到20分钟后过期的客户端浏览器。我已经安装了aws-sdk gem并运行了bundle install等。

我有一个欢迎控制器和一个索引视图。我的控制器中有以下代码:

  class WelcomeController < ApplicationController

  def index
  end

  def doc_download

    require 'aws-sdk'

    s3 = Aws::S3::Client.new(
        access_key_id: 'mykey',
        secret_access_key: 'mykey'
    )

    aws_resource = Aws::S3::Resource::new
    aws_resource.bucket('mynewapp.herokuapp.com').object('1.jpg').presigned_url(:get, expires_in: 20.minutes)

    @download = doc_download

  end

end

然后在我看来

<p><%= link_to 'Download', @download %></p>

但是没有任何事情发生,当我点击“下载”链接时页面会刷新。

任何帮助都非常感激,花了几天的时间试图从试图完成此任务的许多不同帖子中找出答案。

4 个答案:

答案 0 :(得分:0)

不确定它是否有效,因为我对Paperclip的方式比较熟悉,但你可以试试这个:

s3_client = Aws::S3::Client.new(
        access_key_id: 'mykey',
        secret_access_key: 'mykey'
    )

@download = puts Aws::S3::Object.new(
        key: '1.jpg',
        bucket_name: 'mynewapp.herokuapp.com',
        client: s3_client
).presigned_url(:get, expires_in: 60 * 60)

我从这里获得灵感http://docs.ceph.com/docs/jewel/radosgw/s3/ruby/

答案 1 :(得分:0)

感谢Maxence帮助我一路走来,这是适合我的代码:

在我的Gemfile中

gem 'aws-sdk'

我的控制器:

class WelcomeController < ApplicationController

  def index

    doc_download

  end

  def doc_download

    require 'aws-sdk'

    Aws.config.update(
        region: 'eu-west-2',
        endpoint: 'https://s3.eu-west-2.amazonaws.com',
        access_key_id: 'mykey',
        secret_access_key: 'mykey',
    )

    s3_client = Aws::S3::Client.new

    @download = Aws::S3::Object.new(
        key: 'myfilename', bucket_name: 'mybucketname', client: s3_client).presigned_url(:get, expires_in: 60 * 60
    )

  end

end

然后在我的索引视图中显示链接(来自欢迎控制器)

<p><%= link_to 'Download', @download %></p>

只是为了确认功能,这将输出一个安全的可过期链接到s3存储桶,供用户下载文件,他们可能需要先付费等等。

答案 2 :(得分:0)

我使用aws-sdk-s3 gem(版本1.8.2)也遇到了类似的问题。在我的情况下,我不得不将文件上传到S3,然后向用户显示一个过期的URL。我得到的代码看起来像这样:

# Upload a file to S3 and return an expiring URL
# @param [IOStream] file
# @param [String] file_path
# @param optional [Integer] expiring_in_seconds (600)
# @returns [String] expiring and pre-signed URL
def upload_file(file, file_path, expiring_in_seconds = 600)

  # upload file to S3
  client = Aws::S3::Client.new
  client.put_object({
                        body: file,
                        bucket: ENV['S3_BUCKET_NAME'],
                        key: file_path
                    })

  # create an S3 object reference
  obj =  Aws::S3::Object.new(ENV['S3_BUCKET_NAME'], file_path)

  # create pre-signed url
  obj.presigned_url(:get, expires_in: expiring_in_seconds)
end

请记住,我的环境变量中包含以下AWS凭据和设置:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_REGION
  • S3_BUCKET_NAME
  • S3_SIGNATURE_VERSION

答案 3 :(得分:-2)

我认为现在将提供Rails 5.2 ActiveStorage http://edgeguides.rubyonrails.org/active_storage_overview.html