AWS s3 access PRIVATE bucket url from rails app

2.3k Views Asked by At

I'm new to RoR.

I'm creating a small app that uploads images and saves them in S3, the user cant attach all the images in a zip file and send it via email,to accomplish that im using rubyzip gem.

Locally it works fine (Im following the gem documentation)

https://github.com/rubyzip/rubyzip/

But in production for the "ZIP" action I need to give a source folder (in which is saved the image) and since all my images are saved in s3 bucket I give a path like the following:

folder = 'https://'bucket-name'.s3.amazonaws.com/'

After research i fond similar cases, but none of them work for me, for example I tried How to retrieve attachment url with Rails Active Storage with S3 and it give me "No such file or directory"

2018-11-15T00:44:27.082416+00:00 app[web.1]: I, [2018-11-15T00:44:27.082337 #4]  INFO -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062] Completed 500 Internal Server Error in 1532ms (ActiveRecord: 21.4ms)
2018-11-15T00:44:27.082915+00:00 app[web.1]: F, [2018-11-15T00:44:27.082844 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062]
2018-11-15T00:44:27.082988+00:00 app[web.1]: F, [2018-11-15T00:44:27.082916 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062] Errno::ENOENT (No such file or directory @ rb_file_s_lstat - https://bucket-name.s3.amazonaws.com):
2018-11-15T00:44:27.083054+00:00 app[web.1]: F, [2018-11-15T00:44:27.082985 #4] FATAL -- : [db52fa26-32c2-4f7e-a766-7d39fd3ef062]

My bucket is private so, make sense that it doesn't let me access it until I provide correct credentials, and here is the part where I dont have idea how to send the signature in the url to authenticate. I have tried something like the following but it keeps giving me weird simbols

kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + secret_access_key, dateStamp)
    kRegion = OpenSSL::HMAC.digest('sha256', kDate, regionName)
    kService = OpenSSL::HMAC.digest('sha256', kRegion, serviceName)
    signature = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")


    puts("#{s3_base_url}?AWSAccessKeyId=#{access_key_id}
            &Expires=#{expiration_date}
            &Signature=#{signature}")

this is the result when i print the signature

https://bucket-name.s3.amazonaws.com?AWSAccessKeyId=my-access-key
            &Expires=1542416076
            &Signature=Q�����>�9`o���r}�9��`�m��g��

Ps. Im also have created a IAM user with admin privileges

Thanks, Im using ruby 2.5.1 and rails 5.2.0 Im super new with dealing with AMAZON so excuse if my question is to obvious

1

There are 1 best solutions below

0
On

I'm not sure about constructing a signed URL manually; I've never tried it. However, the AWS gem has a presigned_url method for S3 objects that will construct them for you. You can then use that URL to access the object in the private bucket.

See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#presigned_url-instance_method

bucket = Aws::S3::Bucket.new bucket_name
object = bucket.object object_key
object.presigned_url(:get, expires_in: expiry)