Skip to content

Instantly share code, notes, and snippets.

@spaomalley
Last active December 16, 2015 03:59
Show Gist options
  • Save spaomalley/5374222 to your computer and use it in GitHub Desktop.
Save spaomalley/5374222 to your computer and use it in GitHub Desktop.
This is a javascript implementation of the OAuth 1.0a workflow. It uses the Crypto-Js library.
function oauth(method, url,token,tokenSecret){
var consumerKey = "";
var consumerSecret = "";
var params = {
"oauth_consumer_key": consumerKey,
"oauth_nonce": generateNonce(),
"oauth_signature_method": "HMAC-SHA1"
}
if(token!=null){
params["oauth_token"] = token;
}
params["oauth_timestamp"]= generateTimestamp();
params["oauth_version"]="1.0";
var normalizedString=normalizeString(NVPConvert(ksort(params)));
var basestring='';
basestring+= encodeURIComponent(method.toUpperCase()) + "&";
basestring+= encodeURIComponent(url) + "&";
basestring+= encodeURIComponent(normalizedString);
var key;
if(token!=null){
key = encodeURIComponent(consumerSecret) + "&" + encodeURIComponent(tokenSecret);
}else{
key = encodeURIComponent(consumerSecret) + "&";
}
var s = CryptoJS.HmacSHA1( basestring, key);
var sig =CryptoJS.enc.Base64.stringify(s);
params["oauth_signature"]=encodeURIComponent(sig);
var concatHeaders=concatHeader(NVPConvert(ksort(params)));
var sendHeaders="OAuth " + concatHeaders;
return sendHeaders;
}
function sendRequest(method,url,token,tokenSecret){
var httpCall = makeHttpObject();
httpCall.open(method, url, false);
httpCall.setRequestHeader("Authorization", oauth(method,url,token,tokenSecret));
httpCall.setRequestHeader("Accept", "text/JSON");
httpCall.send(null);
return httpCall
}
function work(){
var requestToken = { "url": "https://test.api.mxmerchant.com/v1/oauth/1a/requesttoken", "method": "POST"};
var accessToken = { "url": "https://test.api.mxmerchant.com/v1/oauth/1a/accesstoken", "method": "POST"};
var httpData=sendRequest(requestToken.method, requestToken.url,null,null);
var tokenData=findTokens(httpData.responseText);
console.log(tokenData[0] + " " + tokenData[1]);
var accessHttpData=sendRequest(accessToken.method, accessToken.url,tokenData[0],tokenData[1]);
var accessTokenData=findTokens(accessHttpData.responseText);
console.log(accessTokenData[0] + " " + accessTokenData[1]);
}
function generateCSecret(consumerSecret){
return consumerSecret.toString(CryptoJS.enc.Base64);
}
function generateNonce(){
var unixtime_ms = new Date().getTime();
var sec = parseInt(unixtime_ms / 1000);
return sec;
}
function generateTimestamp(){
var time=new Date().getTime();
return time;
}
function makeHttpObject() {
try {return new XMLHttpRequest();}
catch (error) {}
try {return new ActiveXObject("Msxml2.XMLHTTP");}
catch (error) {}
try {return new ActiveXObject("Microsoft.XMLHTTP");}
catch (error) {}
throw new Error("Could not create HTTP request object.");
}
function normalizeString(normPieces){
var normalizedString='';
for(var i=0;i<=normPieces.length-1;i++){
if (i==normPieces.length-1){
normalizedString+=normPieces[i];
}
else{
normalizedString+=normPieces[i]+"&";
}
}
return normalizedString;
}
function NVPConvert(arrayPieces){
var chunks=[];
for ( var key in arrayPieces){
chunks.push (key + "=" + arrayPieces[key]);
}
return chunks;
}
function concatHeader(normPieces){
var headerString='';
for(var i=0;i<=normPieces.length-1;i++){
if (i==normPieces.length-1){
headerString+=normPieces[i];
}
else{
headerString+=normPieces[i]+",";
}
}
return headerString;
}
function findTokens(responseText){
var tokenData=responseText.split('&');
var oauthTokenData = tokenData[0].split('=');
var oauthToken= oauthTokenData[1];
var oauthTokenSecretData = tokenData[1].split('=');
var oauthTokenSecret=oauthTokenSecretData[1];
return [oauthToken,oauthTokenSecret ];
}
function ksort (inputArr, sort_flags) {
var tmp_arr = {},
keys = [],
sorter, i, k, that = this,
strictForIn = false,
populateArr = {};
switch (sort_flags) {
case 'SORT_STRING':
// compare items as strings
sorter = function (a, b) {
return that.strnatcmp(a, b);
};
break;
case 'SORT_LOCALE_STRING':
// compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
var loc = this.i18n_loc_get_default();
sorter = this.php_js.i18nLocales[loc].sorting;
break;
case 'SORT_NUMERIC':
// compare items numerically
sorter = function (a, b) {
return ((a + 0) - (b + 0));
};
break;
// case 'SORT_REGULAR': // compare items normally (don't change types)
default:
sorter = function (a, b) {
var aFloat = parseFloat(a),
bFloat = parseFloat(b),
aNumeric = aFloat + '' === a,
bNumeric = bFloat + '' === b;
if (aNumeric && bNumeric) {
return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
} else if (aNumeric && !bNumeric) {
return 1;
} else if (!aNumeric && bNumeric) {
return -1;
}
return a > b ? 1 : a < b ? -1 : 0;
};
break;
}
// Make a list of key names
for (k in inputArr) {
if (inputArr.hasOwnProperty(k)) {
keys.push(k);
}
}
keys.sort(sorter);
// BEGIN REDUNDANT
this.php_js = this.php_js || {};
this.php_js.ini = this.php_js.ini || {};
// END REDUNDANT
strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
populateArr = strictForIn ? inputArr : populateArr;
// Rebuild array with sorted key names
for (i = 0; i < keys.length; i++) {
k = keys[i];
tmp_arr[k] = inputArr[k];
if (strictForIn) {
delete inputArr[k];
}
}
for (i in tmp_arr) {
if (tmp_arr.hasOwnProperty(i)) {
populateArr[i] = tmp_arr[i];
}
}
return strictForIn || populateArr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment