How to store data on S3 and secure user access to the API / iOS client with rails?

I am new to writing Rails and APIs. I need help solving S3. Here is my problem.

I am writing an API for an iOS application where users log in with the Facebook API on iOS. The server checks the user for problems with the Facebook token for the iOS user and issues a temporary session token. From now on, the user needs to download content that is stored in S3. This content belongs only to the user and a subset of his friends. This user can add more content on S3, which can be accessed by the same group of people. I think this is like attaching a file to a Facebook group ...

There are two ways the user interacts with S3: leave it on the server or force the server to issue a temporary S3 token (not sure about the possibilities here), and the user can directly type the content URLs to S3. I found this question talking about approaches, however it is really outdated (2 years ago): Architectural question and the question of downloading photos from the iPhone application and S3

So the questions are:

  • Is there a way to restrict user access to certain content on S3 when issuing a temporary token? How can i do this? Suppose there are ... say, 100,000 or more users.
  • Can I let an iOS device directly pull this content?
  • Or should the server control all the content passing through (this, of course, solves the problem)? Does this mean that I need to upload all the content to the server before transferring it to connected users?
  • If you know the rails ... can I use paperclip and aws-sdk gems to achieve this setup?

Sorry for a few questions, and I appreciate any understanding of the problem. Thank:)

+80
api ruby-on-rails amazon-s3 amazon-ec2 client-server
May 30 '12 at 6:28
source share
2 answers

Using aws-sdk gem , you can get a temporary signed URL for any S3 object by calling url_for :

 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 

This will give you a signed, temporary use-only URL for this object in S3. It expires after 20 minutes (in this example), and this is only useful for one object.

If you have many objects that the client needs, you will need to issue many signed URLs.

Or should it allow the server to manage all the content (this, of course, decides security)? Does this mean that I need to upload all the content to the server before transferring it to connected users?

Please note that this does not mean that the server needs to download every object, it only needs to authenticate and authorize certain clients to access certain objects in S3.

Amazon API Docs: http://docs.amazonwebservices.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationQueryStringAuth

+104
Jun 05 2018-12-12T00:
source share

The answers above use the old aws-sdk-v1 pearl, not the new aws-sdk-resources version 2.

New way:

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

where your_object_key is the path to your file. If you need to see this, you should use something like:

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

This information is amazingly difficult to dig out, and I almost gave up and used an old stone.

Link

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

+35
Jul 10 '15 at 18:58
source share



All Articles