- Notifications
You must be signed in to change notification settings - Fork175
Signs and prepares Node.js requests using AWS Signature Version 4
License
mhart/aws4
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A small utility to signvanilla Node.js http(s) request options using Amazon'sAWS Signature Version 4.
If you want to sign and send AWS requests usingfetch()
, then check outaws4fetch – otherwise you can also bundle this library for usein older browsers.
The only AWS service I know of thatdoesn't support v4 isSimpleDB(it only supportsAWS Signature Version 2).
It also provides defaults for a number of core AWS headers andrequest parameters, making it very easy to query AWS services, orbuild out a fully-featured AWS library.
varhttps=require('https')varaws4=require('aws4')// to illustrate usage, we'll create a utility function to request and pipe to stdoutfunctionrequest(opts){https.request(opts,function(res){res.pipe(process.stdout)}).end(opts.body||'')}// aws4 will sign an options object as you'd pass to http.request, with an AWS service and regionvaropts={host:'my-bucket.s3.us-west-1.amazonaws.com',path:'/my-object',service:'s3',region:'us-west-1'}// aws4.sign() will sign and modify these options, ready to pass to http.requestaws4.sign(opts,{accessKeyId:'',secretAccessKey:''})// or it can get credentials from process.env.AWS_ACCESS_KEY_ID, etcaws4.sign(opts)// for most AWS services, aws4 can figure out the service and region if you pass a hostopts={host:'my-bucket.s3.us-west-1.amazonaws.com',path:'/my-object'}// usually it will add/modify request headers, but you can also sign the query:opts={host:'my-bucket.s3.amazonaws.com',path:'/?X-Amz-Expires=12345',signQuery:true}// and for services with simple hosts, aws4 can infer the host from service and region:opts={service:'sqs',region:'us-east-1',path:'/?Action=ListQueues'}// and if you're using us-east-1, it's the default:opts={service:'sqs',path:'/?Action=ListQueues'}aws4.sign(opts)console.log(opts)/*{ host: 'sqs.us-east-1.amazonaws.com', path: '/?Action=ListQueues', headers: { Host: 'sqs.us-east-1.amazonaws.com', 'X-Amz-Date': '20121226T061030Z', Authorization: 'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/sqs/aws4_request, ...' }}*/// we can now use this to query AWSrequest(opts)/*<?xml version="1.0"?><ListQueuesResponse xmlns="https://queue.amazonaws.com/doc/2012-11-05/">...*/// aws4 can infer the HTTP method if a body is passed in// method will be POST and Content-Type: 'application/x-www-form-urlencoded; charset=utf-8'request(aws4.sign({service:'iam',body:'Action=ListGroups&Version=2010-05-08'}))/*<ListGroupsResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">...*/// you can specify any custom option or header as per usualrequest(aws4.sign({service:'dynamodb',region:'ap-southeast-2',method:'POST',path:'/',headers:{'Content-Type':'application/x-amz-json-1.0','X-Amz-Target':'DynamoDB_20120810.ListTables'},body:'{}'}))/*{"TableNames":[]}...*/// you can also specify extra headers to ignore during signingrequest(aws4.sign({host:'07tjusf2h91cunochc.us-east-1.aoss.amazonaws.com',method:'PUT',path:'/my-index',body:'{"mappings":{}}',headers:{'Content-Type':'application/json','X-Amz-Content-Sha256':'UNSIGNED-PAYLOAD'},extraHeadersToIgnore:{'content-length':true}}))// and headers to include that would normally be ignoredrequest(aws4.sign({service:'mycustomservice',path:'/whatever',headers:{'Range':'bytes=200-1000, 2000-6576, 19000-'},extraHeadersToInclude:{'range':true}}))// The raw RequestSigner can be used to generate CodeCommit Git passwordsvarsigner=newaws4.RequestSigner({service:'codecommit',host:'git-codecommit.us-east-1.amazonaws.com',method:'GIT',path:'/v1/repos/MyAwesomeRepo',})varpassword=signer.getDateTime()+'Z'+signer.signature()// see example.js for examples with other services
Calculates and populates any necessary AWS headers and/or requestoptions onrequestOptions
. ReturnsrequestOptions
as a convenience for chaining.
requestOptions
is an object holding the same options that the Node.jshttp.requestfunction takes.
The following properties ofrequestOptions
are used in the signing orpopulated if they don't already exist:
hostname
orhost
(will try to be determined fromservice
andregion
if not given)method
(will use'GET'
if not given or'POST'
if there is abody
)path
(will use'/'
if not given)body
(will use''
if not given)service
(will try to be calculated fromhostname
orhost
if not given)region
(will try to be calculated fromhostname
orhost
or use'us-east-1'
if not given)signQuery
(to sign the query instead of adding anAuthorization
header, defaults to false)extraHeadersToIgnore
(an object with lowercase header keys to ignore when signing, eg{ 'content-length': true }
)extraHeadersToInclude
(an object with lowercase header keys to include when signing, overriding any ignores)headers['Host']
(will usehostname
orhost
or be calculated if not given)headers['Content-Type']
(will use'application/x-www-form-urlencoded; charset=utf-8'
if not given and there is abody
)headers['Date']
(used to calculate the signature date if given, otherwisenew Date
is used)
Your AWS credentials (which can be found in yourAWS console)can be specified in one of two ways:
- As the second argument, like this:
aws4.sign(requestOptions,{secretAccessKey:"<your-secret-access-key>",accessKeyId:"<your-access-key-id>",sessionToken:"<your-session-token>"})
- From
process.env
, such as this:
export AWS_ACCESS_KEY_ID="<your-access-key-id>"export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"export AWS_SESSION_TOKEN="<your-session-token>"
(will also useAWS_ACCESS_KEY
andAWS_SECRET_KEY
if available)
ThesessionToken
property andAWS_SESSION_TOKEN
environment variable are optional for signingwithIAM STS temporary credentials.
Withnpm do:
npm install aws4
Can also be usedin the browser.
Thanks to@jed for hisdynamo-client lib where I firstcommitted and subsequently extracted this code.
Also thanks to theofficial Node.js AWS SDK for givingme a start on implementing the v4 signature.
About
Signs and prepares Node.js requests using AWS Signature Version 4