Reputation: 2030
I am attempting to follow the AWS API for getting a JavaScript file from a private S3 bucket. The guide is here: Signing and Authenticating REST Requests
The environment is a browser with jQuery, so this is a JavaScript implementation. I have worked through what I considered to be the hard part - signing the request with the secret key. But now I am hung up on something supposedly easy. I have this resulting REST request to transmit:
GET /gss3/sayHello.js HTTP/1.1
Host: gss3.s3.amazonaws.com
Date: Thu Feb 07 2013 08:16:25 GMT-0500 (Eastern Standard Time)
Authorization: AWS AKIAJTURNBE6SXNTVVGQ:eWJOLZnj6Eja3CEC2CyifeURnxg=
Since this is a call to s3.amazonaws.com from www.mydomain.com, I was looking at JSONP to get around the same origin policy. However, I don't see any way to add extra headers to a jQuery JSONP call, and to authenticate with AWS you have to pass that 4th line:
Authorization: AWS AKIAJTURNBE6SXNTVVGQ:eWJOLZnj6Eja3CEC2CyifeURnxg=
So my question is this: how the heck do I transmit this REST request to AWS in my browser / jQuery environment? What am I missing here? Thanks gang....
Upvotes: 3
Views: 2602
Reputation: 2030
Although this source was written for PHP, the blog Amazon AWS S3 Query String Authentication with PHP shows how to compile a plain old querystring and pass the signature as a parameter to S3.
$url .= '?AWSAccessKeyId='.$awsKeyId
.'&Expires='.$expires
.'&Signature='.$signature;
Using the crypto-js and converting to Javascript then gives us something like this:
var filePath = "/bucket/file.js";
var dateTime = Math.floor(new Date().getTime() / 1000) + 300; // allows for 5 minutes clock diff
var stringToSign = "GET\n\n\n" + dateTime + "\n" + filePath;
var signature = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(stringToSign, secretAccessKey));
var queryString = "?AWSAccessKeyId=" + accessKeyId + "&Expires=" + dateTime + "&Signature=" + encodeURIComponent(signature);
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://s3.amazonaws.com/bucket/file.js" + queryString;
$("head").append(script); // jQuery version
And there you go, almost the whole banana written for you. I hope this helps someone out.
Upvotes: 5
Reputation: 42344
You can't add headers to a JSON-P call as a JSON-P call is just a dynamic scrip tag appended to your webpage, unless S3 supports passing it as a GET param.
If you're using JSON-P then cross-domain issue no longer matter. As long as its valid JS it can be pulled in to your webpage from any domain. You just need to make sure the S3 file in question has a permission of viewable by anyone.
The last way to do it, is enable your S3 bucket with CORS (cross domain ajax) which is a new feature S3 supports. Then you can do vanilla ajax calls cross domain to your s3 bucket and add extra headers to your hearts content.
Upvotes: 0