轨道3,回形针+ S3 - HOWTO商店的实例和保护访问 [英] Rails 3, paperclip + S3 - Howto Store for an Instance and Protect Access

查看:169
本文介绍了轨道3,回形针+ S3 - HOWTO商店的实例和保护访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Rails 3应用程序使用回形针,意图存储数据的S3。

在应用程序中,用户属于一个实例。

我想整个存储每个实例的所有车型中的数据。并希望prevent从实例A用户访问,或能够从实例B加载数据。

什么是处理这个问题的最好方法是什么?谢谢

解决方案

我其实只是实现了授权S3的URL在我的的Ruby on Rails 3 应用程序的回形针。让我分享我是如何做到了这一点。

所以我做了什么,你可能想要的东西是很容易实现的。 我给大家举一个例子:

文件对象模型

  has_​​attached_file:附件,
  :PATH => 文件/:ID /:基本名称:扩展名,
  :存储=> :S3,
  :s3_permissions => :私人,
  :s3_credentials => File.join(Rails.root,'配置','s3.yml')
 

FileObjectsController 控制器

 高清下载
    @file_object = FileObject.find(PARAMS [:ID])
    redirect_to时(@ file_object.attachment.expiring_url(10))
  结束
 

我相信这是非常简单的。您在 FileObjectsController 回形针附件添加到文件对象模型,然后有一个动作(下载为例)。这样,你可以做一些应用程序级别的授权,从你的控制器中使用的before_filter 或什么的。

expiring_url()方式(所提供的回形针)的 @ file_object.attachment 基本要求Amazon S3的一键这使得文件与该特定键访问。在 expiring_url()的第一个参数方法接受一个整数,再presents的要在其中提供的URL过期。

在我的应用程序是当前设置为 10 @ file_object.attachment.expiring_url(10)),这样当用户请求一个文件时,用户可以随时到经过我的应用程序,在例如 myapp.com/file_objects/3/download 得到亚马逊,用户随后立即将使用下载文件,因为我们使用了它一个新的有效的URL redirect_to时下载方法的行动。用户点击下载所以基本上10秒钟后的行动,该链接已经过期,并且用户已经(或仍然是)高兴地下载文件,而它仍然不受任何非授权用户。

我甚至试图将 expiring_url(1)这样的URL,用户触发的Amazon S3请求的URL后立即失效。这为我工作地方,但从来没有使用过的产品,你可以试试这一点。然而,我将它设置为10秒,得到服务器的时间来响应一个短的时间。伟大工程,到目前为止,我怀疑任何人将在10秒内劫持别人的URL就被创建后年代,更别说知道网址是什么。

额外安全措施,我把刚生成的密钥作为对创建的每一个文件,以便我的网址总是这样的:

  has_​​attached_file:附件,
  :PATH => 文件/:ID /:SECRET_KEY /:基本名称:扩展名
 

让每一个URL都有它独特的 SECRET_KEY 在它的路径,使其难以在时间的URL访问内劫持。你要知道,虽然URL到您的文件保持不变,可访问来自亚马逊S3提供了额外的参数,到期:

<$p$p><$c$c>http://s3.amazonaws.com/mybucket/files/f5039a57acc187b36c2d/my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

注意这个部分,这是关键亚马逊产生并到期,这使得该文件暂时访问:

<$p$p><$c$c>my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

这就是它的全部。这与你的文件每一个请求改变,如果通过下载请求操作。

希望这有助于!

I have a Rails 3 app with paperclip, with the intent to store data on S3.

In the app, Users belong to an instance.

I would like the data stored across all the models per instance. And would like to prevent a user from Instance A from accessing, or being able to load data from Instance B.

What's the best way to handle this? thanks

解决方案

I actually just implemented authorized S3 url's in my Ruby on Rails 3 application with Paperclip. Let me share how I accomplished this.

So what I did, and what you probably want is quite easy to implement. Let me give you an example:

FileObject model

has_attached_file :attachment,
  :path           => "files/:id/:basename.:extension",
  :storage        => :s3,
  :s3_permissions => :private,
  :s3_credentials => File.join(Rails.root, 'config', 's3.yml')

FileObjectsController controller

  def download
    @file_object = FileObject.find(params[:id])
    redirect_to(@file_object.attachment.expiring_url(10))
  end

I believe this is quite straightforward. You add the Paperclip attachment to the FileObject model and then have an action (download for example) in the FileObjectsController. This way you can do some application level authorization from within your controller with a before_filter or something.

The expiring_url() method (provided by Paperclip) on the @file_object.attachment basically requests Amazon S3 for a key which makes the file accessible with that particular key. The first argument of the expiring_url() method takes an integer which represents the amount of seconds in which you want the provided URL to expire.

In my application it is currently set to 10 (@file_object.attachment.expiring_url(10)) so when the user requests a file, the user ALWAYS has to go through my application at for example myapp.com/file_objects/3/download to get a new valid URL from Amazon, which the user then instantly will be using to download the file since we're using the redirect_to method in the download action. So basically 10 seconds after the user hits the download action, the link already expired and the user has (or is still) happily downloading the file, while it remains protected from any non-authorized users.

I have even tried to set expiring_url(1) so that the URL instantly expires after the user triggers the Amazon S3 request for the URL. This worked for me locally, but never used it in production, you can try that too. However, I set it to 10 seconds to give the server a short period of time to respond. Works great so far and I doubt anyone will hijack someone's URL within 10 seconds after it's been created, let alone know what the URL is.

Extra security measure I took is just to generate a secret key for every file on create so my URL's always look like this:

has_attached_file :attachment,
  :path => "files/:id/:secret_key/:basename.:extension"

So that every URL has it's unique secret_key in it's path, making it harder to hijack within the time the URL is accessible. Mind you that, while the URL to your file remains the same, the accessibility comes from the additional parameters that Amazon S3 provides which expire:

http://s3.amazonaws.com/mybucket/files/f5039a57acc187b36c2d/my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

Notice this part, which is the key Amazon generates and expires which makes the file temporarily accessible:

my_file.pdf?AWSAccessKeyId=AKIAIPPJ2IPWN5U3O1OA&Expires=1288526454&Signature=5i4%2B99rUwhpP2SbNsJKhT/nSzsQ%3D

That's what it's all about. And this changes with every request for your file if requested through the download action.

Hope this helps!

这篇关于轨道3,回形针+ S3 - HOWTO商店的实例和保护访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆