如何在S3中存储数据并允许用户使用Rails API / iOS客户端以安全的方式访问?

我是编写Rails和API的新手。 我需要一些S3存储解决scheme的帮助。 这是我的问题。

我正在为iOS应用程序编写一个API,其中用户使用iOS上的Facebook APIlogin。 服务器根据令牌Facebook发给iOS用户的用户validation用户,并发出一个临时的会话令牌。 从这一点,用户需要下载存储在S3中的内容。 这个内容只属于用户和他的朋友的一个子集。 这个用户可以添加更多的内容到S3可以被同一群人访问。 我想这是类似的附加文件到Facebook组…

有两种方式用户可以与S3进行交互…将其留给服务器或让服务器发出一个临时的S3令牌(不知道这里的可能性),用户可以直接点击内容URL到S3。 我发现这个问题谈论的方法,但是,它真的是过时的(2年前): build筑和devise问题上传照片从iPhone应用程序和S3

所以问题:

  • 有没有办法限制用户在临时令牌发布时仅访问S3上的一些内容? 我该怎么做? 假设有…说10万或更多的用户。
  • 让iOS设备直接提取这些内容是一个好主意吗?
  • 或者应该让服务器控制所有传递的内容(这当然解决了安全性)? 这是否意味着我必须下载所有的内容到服务器,然后交给连接的用户?
  • 如果你知道铁轨…我可以使用回形针和aws-sdkgem来达到这种安装吗?

对于多个问题抱歉,我很欣赏对这个问题的深入了解。 谢谢 :)

使用aws-sdk gem ,您可以通过调用url_for来获取任何S3对象的临时签名url:

 s3 = AWS::S3.new( :access_key_id => 1234, :secret_access_key => abcd ) object = s3.buckets['bucket'].objects['path/to/object'] object.url_for(:get, { :expires => 20.minutes.from_now, :secure => true }).to_s 

这会给你一个签名的临时使用的URL,只有在S3中的那个对象。 它在20分钟后过期(在这个例子中),它只对那个对象有效。

如果客户端需要大量对象,则需要发布大量签名的URL。

或者应该让服务器控制所有传递的内容(这当然解决了安全性)? 这是否意味着我必须下载所有的内容到服务器,然后交给连接的用户?

请注意,这并不意味着服务器需要下载每个对象,只需要对特定的客户端进行身份validation和授权即可访问S3中的特定对象。

来自Amazon的API文档: http : //docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth

上面的答案使用旧的aws-sdk-v1 gem而不是新的aws-sdk-resources版本2。

新的方法是:

 aws_resource = Aws::S3::Resource::new aws_resource.bucket('your_bucket').object('your_object_key').presigned_url(:get, expires_in: 1*20.minutes) 

其中your_object_key是文件的path。 如果你需要查看,你会使用类似于:

 s3 = Aws::S3::Client::new keys = [] s3.list_objects(bucket: 'your_bucket', prefix: 'your_path').contents.each { |e| keys << e.key } 

这些信息非常难以挖掘,我几乎只是放弃了,使用了旧的gem。

参考

http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Object.html#presigned_url-instance_method