Reputation: 2633
I need to be able to upload large (1+ gb) files to S3 from the user's browser. Sending them through the application server (PHP) is simply not an option because of size and load constraints.
I would like to use the AWS Javascript SDK to do this, as shown here: http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Uploading_a_local_file_using_the_File_API
The problem is, the Javascript SDK only (officially) lists a few authentication methods, and it isn't clear how you can make the SDK use "AWS Signature V4" authentication, as shown here: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
The question is: Can you use "Signature V4" with the "AWS JS SDK"?
Edit: It sounds like maybe I need to use the "Security Token Service" : http://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html Can anyone confirm if this is the right way to go?
More specifics that may be relevant: My use case is in the admin area of an online store, where the admin user is already authenticated by logging into the admin section, but still shouldn't be able to see the master AWS secret key. The AWS JS SDK lets you authenticate with Facebook or other ID providers, but this would be a weird user-experience since the admin has already logged in.
Because this functionality must be packaged into a single module for installation in an ecommerce platform (Magento,) it isn't feasible to ask the installer to also go and create a new IAM role with separate credentials just for the uploader feature.
Upvotes: 2
Views: 5460
Reputation: 151
Adding more info to the accepted answer, you can refer to my blog to see a running version of the code, using AWS Signature version 4.
Will summarize here:
As soon as the user selects a file to be uploaded, do the followings:
Make a call to the web server to initiate a service to generate required params
In this service, make a call to AWS IAM service to get temporary cred
Once you have the cred, create a bucket policy (base 64 encoded string). Then sign the bucket policy with the temporary secret access key to generate final signature
Send the necessary parameters back to the UI
Once this is received, create a html form object, set the required params and POST it.
For detailed info, please refer https://wordpress1763.wordpress.com/2016/10/03/browser-based-upload-aws-signature-version-4/
Upvotes: -1
Reputation: 1700
To upload files from browser to S3 you can use presigned PUT. This way you will not be disclosing the aws secret to the browser. You can use the minio-js library to generate presigned PUT url.
On the server side you can generate the presigned PUT url like this:
var Minio = require('minio')
// find out your s3 end point here:
// http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
var s3Client = new Minio({
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY'
})
var presignedUrl = s3Client.presignedPutObject('bucket', 'object', 24*60*60)
// presignedUrl expires in 1 day
You can pass this presigned URL to the browser which can just do a simple HTTP PUT to amazon s3. The PUT request will succeed because the signature will be part of the presignedUrl.
You can also alternatively use presigned POST to upload too.
Upvotes: 4
Reputation: 225
You have 2 options since hardcoding credentials is never a good choice.
I would suggest you leverage the AWS SDK for JavaScript with AWS Cognito with Developer Authenticated Identities. The scenario you noted is exactly what Cognito was designed to address. You can have the admin log in to the system with your own designed auth method as you are doing now, but use that authorization to generate a token via Cognito that can be used to authenticate for all the AWS services.
For examples of both scenarios, please review the AWS JavaScript Developer Guide: Loading Credentials in the Client's Browser: http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-configuring.html#Loading_Credentials_in_the_Client_s_Browser
References that may also assist you:
Amazon Cognito Developer Authenticated Identities: http://docs.aws.amazon.com/cognito/devguide/identity/developer-authenticated-identities/
Identity Providers and Federation: http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html
AWS SDK for JavaScript Developer Guide: http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/index.html
Upvotes: 1