Created
July 3, 2010 01:21
-
-
Save SeanHayes/462169 to your computer and use it in GitHub Desktop.
Pseudo code for signing OAuth requests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function urlEncode(str){ | |
//everything except [a-zA-Z0-9-_~.] must be percent encoded: http://tools.ietf.org/html/rfc5849#section-3.6 | |
} | |
function hmac_sha1(key, text){ | |
//you'll definitely want a library for this. I used Crypto-JS: http://code.google.com/p/crypto-js/ | |
} | |
function base64me(key, text){ | |
//I used Crypto-JS for this too. | |
} | |
/* | |
httpMethod - string | |
url - string | |
params - key/value array | |
*/ | |
//assume 'GET', 'http://seanhayes.name/', and {foo: ['baz', 'blah'], bar: 'true'} is passed in | |
function signRequest(httpMethod, url, params){ | |
var signature = [];//new, empty array | |
params.sort();//sort by key name in alphabetical order. if duplicate keys, sort those by same method. | |
//first, generate param section of unhashed signature | |
foreach(params as key, value){ | |
//code for detecting whether 'value' is itself an array and iterating through it has been left out | |
signature.append(urlEncode(key)+'='+urlEncode(value)); | |
} | |
signature = signature.join('&') | |
//we now have 'foo=baz&foo=blah&bar=true' | |
//each component gets URL encoded. Yes, even the params part gets URL encoded, AGAIN | |
signature = httpMethod.toUpperCase()+'&'+urlEncode(url)+'&'+urlEncode(signature); | |
//we now have 'GET&http%3A%2F%2Fseanhayes.name%2F&foo%3Dbaz%26foo%3Dblah%26bar%3Dtrue' | |
/* | |
oauth_consumer_secret and oauth_token_secret should be in a namespace accessible to this function | |
For the purposes of this example, oauth_consumer_secret equals 'anonymous'. When starting the authentication process, oauth_token_secret will be an empty string (''). It will change to some other value given to you by the OAuth provider once your token is authorized. | |
*/ | |
var key = urlEncode(oauth_consumer_secret)+'&'+urlEncode(oauth_token_secret); | |
//we'll be using the HMAC-SHA1 encryption method, since it allows anonymous applications to connect (at least with Google) | |
signature = hmac_sha1(key, signature); | |
//Then base64 encode it all. Yes, this should make all the previous URL encoding completely unneccessary, but this is what the spec says. | |
signature = base64me(signature); | |
/* | |
I used Crypto-JS, which involves the following: | |
signature = Crypto.HMAC(Crypto.SHA1, signature, key); | |
signature = Crypto.util.hexToBytes(signature) | |
signature = Crypto.util.bytesToBase64(signature); | |
*/ | |
//You now have a signature in base64 format. | |
//Don't forget to URL encode this before transmitting (base64 text can contain +, /, and =); I left it out here since all the params will probably get url encoded later when the HTTP message is constructed. Yes, this should make the previous base64 encoding completely unneccessary, but this is what the spec says. (I guess maybe it saves more space than all the binary values getting converted to %xx.) | |
return signature; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment