Questions about Amazon AWS integration
I'm trying to use Amazon AWS simpleDB for a project and I am running into an issue with the required signature. I'm hoping someone on here has either successfully incorporated an AWS service, or can at least help me find some functions I "might" be missing.
First, has anyone done this with AWS before?
I've read online that a possible hang up might be that my secret key is not URL encoded, or that the signature is not. Both look like they need to be encoded (one has a "/" in it, the other two "="s. But I cannot find in the documentation or on the forum how to simply url encode a string.
Any (and all) help will be greatly appreciated. Thanks in advance.
Replies
Yes, we finally figured this out. But then we realized our project would also require the use of a server for another part of it, something we are not prepared at this time to pursue, so the project has been shelved. Unfortunately the code I have is just hacked together at this point to prove it will work, so it isn't pretty enough to post right off.
If you are looking to try this and have any specific questions, please, ask them. I'll try to get you as far along as I can.
Well, I think I know (maybe) how to send a REST request, I'm just not sure how to use crypto to create a signature for the request.
Also need to figure out how to make a valid timestamp, but I think I can figure that one out on my own, maybe.
Any help would definitely be appreciated!
Okay I warned you, it's ugly, but here are the a few of the functions I built to get simpleDB working:
First, I created two variables, aKey and sKey, to hold my Amazon access and secret keys, respectively.
Be sure to include the following required modules:
1 2 | local crypto = require("crypto") local mime = require("mime") |
The first set of code is my quick solution to creating a timestamp:
1 2 3 4 5 6 7 8 9 10 11 12 | function twoDigit(n) local r = tostring(n) if string.len(r) < 2 then r = "0"..r; end return r end function getTime() local date = os.date("!*t") return date.year.."-"..twoDigit(date.month).."-"..twoDigit(date.day).."T"..twoDigit(date.hour).."%3A"..twoDigit(date.min).."%3A"..twoDigit(date.sec).."Z" end |
The next piece of code is the hash generator signature thingy (yes, technical term) borrowed from bob.dickinson (thanks Bob!)
1 2 3 4 5 | local function sha1_hmac( key, text ) return crypto.hmac(crypto.sha1, text, key, true) end |
The following is my Create a Domain function, where the passed-in-variable "name" is the name to call the domain.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function createDomain(name) local timeStamp = getTime() local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=CreateDomain&DomainName="..name.."&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15" local signature = mime.b64(sha1_hmac(sKey, toSign)) local myURL = "https://sdb.amazonaws.com/?Action=CreateDomain&AWSAccessKeyId="..aKey.."&DomainName="..name.."&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature local function networkListener( event ) if ( event.isError ) then print( "Network error!") else print ( "RESPONSE: " .. event.response ) save(event.response) end end network.request( myURL, "GET", networkListener ) end |
This next code lists the domains:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function listDomains() local timeStamp = getTime() local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=ListDomains&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15" local signature = mime.b64(sha1_hmac(sKey, toSign)) local myURL = "https://sdb.amazonaws.com/?Action=ListDomains&AWSAccessKeyId="..aKey.."&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature local function networkListener( event ) if ( event.isError ) then print( "Network error!") else print ( "RESPONSE: " .. event.response ) save(event.response) end end network.request( myURL, "GET", networkListener ) end |
This next code performs a "Get Attributes" call. Please note that I hard-coded into the strings the attribute and item names just to get the code tested. Like I said, I shelved this project due to other concerns. Again, the passed-in-variable "name" is the domain you are checking.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function getAttributes(name) local timeStamp = getTime() local toSign = "GET\nsdb.amazonaws.com\n/\nAWSAccessKeyId="..aKey.."&Action=GetAttributes&AttributeName.1=theTest&DomainName="..name.."&ItemName=item_01&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp="..timeStamp.."&Version=2009-04-15" local signature = mime.b64(sha1_hmac(sKey, toSign)) local myURL = "https://sdb.amazonaws.com/?Action=GetAttributes&AWSAccessKeyId="..aKey.."&AttributeName.1=theTest&DomainName="..name.."&ItemName=item_01&SignatureVersion=2&SignatureMethod=HmacSHA1&Timestamp="..timeStamp.."&Version=2009-04-15&Signature="..signature local function networkListener( event ) if ( event.isError ) then print( "Network error!") else print ( "RESPONSE: " .. event.response ) save(event.response) end end network.request( myURL, "GET", networkListener ) end |
So, there you go. Frankencode. But it should get you started. If someone makes use of this please consider submitting a cleaned up version to the code base. Thanks.
Wow, that is amazing, and so much more than I hoped for. That makes my weekend!
Yes, that should be enough I think; it all makes sense, just didn't know how to write it.
Thanks again.
Always glad to help :)
Cool, thanks for the starter code.
It may be worth noting that adding crypto (HTTPS/SSL) means that you are supposed to get special approval for your app.
http://tigelane.blogspot.com/2011/01/apple-itunes-export-restrictions-on.html
@Dotnaught,
Yes, that was one of the things that dissuaded us from pursuing this particular project via Amazon. The signature process requires us to use crypto. It may not be that big a deal to get approval, but we are on to other things at the moment.
Thanks, though, for ensuring this is a complete discussion.
@shane.lipscomb
Thanks a lot for the code.
I've posted a decently patched up version in Code Exchange
http://developer.anscamobile.com/code/amazon-simpledb-api



Did you ever figure this out?