查看在AWS S3上上传的私有映像 - 从秘密访问密钥创建签名

时间:2016-06-14 10:34:55

标签: ruby-on-rails ruby amazon-s3

我通过 Paperclip gem在Rails应用上上传了一些图片,我只想让后端的管理员能够查看。结果,我将它们设置为私有。

然后我四处寻找解决方案,了解管理员如何通过特定链接查看文件。这就是我found

我继续尝试这个,但我正在努力创造所需的签名。公式在上面的链接中给出,并且是:

Signature = URL-Encode( Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) ) );

StringToSign = HTTP-VERB + "\n" +
    Content-MD5 + "\n" +
    Content-Type + "\n" +
    Expires + "\n" +
    CanonicalizedAmzHeaders +
    CanonicalizedResource;  

我不知道我需要在Ruby on Rails上使用哪个库/模块/ gem。通过搜索我发现了aws-s3 gem。我阅读了他们的wiki并看到了这个"从浏览器中访问私有对象"。

所以我安装了它们gem,继续打开我的rails控制台并尝试测试它们。我能够与AWS S3建立连接,但之后我无法做任何事情,因为我收到了错误,例如"未初始化的常量"和" NameError"。

对正确方向的任何提示/指导表示赞赏。

最后请注意,我尝试做的是生成链接,管理员可以使用这些链接在浏览器上查看图像而不是下载它们。从我读到的这就是它的作用。但这是肯定还是只是将它们下载到管理员的计算机上?

3 个答案:

答案 0 :(得分:5)

由于您使用的是Paperclip,因此您可以使用其expiring_url feature。因此,您可以使用#show#download控制器操作重定向到临时URL。没有必要自己实现它。

我将补充一点,虽然上述文档建议过期时间为10分钟,但我发现如果您的服务器时钟偏向一个方向而S3偏向另一个方向,则该网址可以expire before it exists 。所以也许20或30分钟更安全。

显然,如果你添加一个像这样的控制器动作,你应该确保只允许管理员使用它。

答案 1 :(得分:4)

首先,能够在浏览器中查看图像或能够下载图像之间没有区别。无论哪种方式,用户的浏览器都会获得构成图像的字节,并可以随心所欲地执行任何操作。

亚马逊提供aws-sdk gem作为官方支持的访问其服务的方式,包括s3。要生成s3预先分配的URL,您可以执行类似

的操作
s3 = Aws::S3::Resource.new(region: "us-east-1")
s3.bucket("bucket-name").object("key/for/object").presigned_url("get", expires_in: 3600)

返回有效期为1小时的链接(假设您有实例提供凭据或具有您的凭据的环境变量AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY。如果不是,则需要在创建资源对象时指定。)

答案 2 :(得分:1)

定义可下载?可用于实现对轨道的用户访问权限的方法。为简单起见,它只允许所有登录用户访问该轨道,但您可以将其替换为您的应用所需的任何逻辑。

def downloadable?(user)
    user != :guest
end

并像这样修改你的attachemnet模型

has_attached_file :mp3,
                  :url => ':s3_domain_url',
                  :path => 'assets/:class/:id/:style.:extension',
                  :storage => :s3,
                  :s3_credentials => File.join(Rails.root, 'config', 's3.yml'),
                  :s3_permissions => 'authenticated-read',
                  :s3_protocol => 'http'

have a look at this