Coder Social home page Coder Social logo

oauth-1.0a's Introduction

OAuth 1.0a Request Authorization semaphore

Join the chat at https://gitter.im/ddo/oauth-1.0a version download coverage climate dependency

OAuth 1.0a Request Authorization for Node and Browser

Send OAuth request with your favorite HTTP client (request, jQuery.ajax...)

No more headache about OAuth 1.0a's stuff or "oauth_consumer_key, oauth_nonce, oauth_signature...." parameters, just use your familiar HTTP client to send OAuth requests.

Tested on some popular OAuth 1.0a services:

  • Twitter
  • Flickr
  • Bitbucket
  • Openbankproject(HMAC-SHA256)

Quick Start

const crypto = require('crypto')
const OAuth = require('oauth-1.0a')

const oauth = OAuth({
    consumer: { key: '<your consumer key>', secret: '<your consumer secret>' },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto
            .createHmac('sha1', key)
            .update(base_string)
            .digest('base64')
    },
})

Get OAuth request data that can be easily used with your http client:

oauth.authorize(request, token)

Or if you want to get as a header key-value pair:

oauth.toHeader(oauth_data)

Crypto

Starting with version 2.0.0, crypto/hash stuff is separated. oauth-1.0a will use your hash_function to sign.

Example

Node.js

const crypto = require('crypto')

function hash_function_sha1(base_string, key) {
    return crypto
        .createHmac('sha1', key)
        .update(base_string)
        .digest('base64')
}

const oauth = OAuth({
    consumer: { key: '<your consumer key>', secret: '<your consumer secret>' },
    signature_method: 'HMAC-SHA1',
    hash_function: hash_function_sha1,
})
  • sha1: crypto.createHmac('sha1', key).update(base_string).digest('base64');
  • sha256: crypto.createHmac('sha256', key).update(base_string).digest('base64');

Browser

Using Google's CryptoJS

  • sha1: CryptoJS.HmacSHA1(base_string, key).toString(CryptoJS.enc.Base64);
  • sha256: CryptoJS.HmacSHA256(base_string, key).toString(CryptoJS.enc.Base64);

Installation

Node.js

$ npm install oauth-1.0a --production
  • You can use the native crypto package for hash_function.
  • It is possible for Node.js to be built without including support for the crypto module. In such cases, calling require('crypto') will result in an error being thrown.
  • You can use your own hash function which has format as:
function(base_string, key) return <string>

Browser

Download oauth-1.0a.js here

And also your crypto lib. For example CryptoJS

<!-- sha1 -->
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha1.js"></script>
<!-- sha256 -->
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script>
<script src="oauth-1.0a.js"></script>

Example

Work with the request library (Node.js):

// Dependencies
const request = require('request')
const OAuth = require('oauth-1.0a')
const crypto = require('crypto')

// Initialize
const oauth = OAuth({
    consumer: {
        key: 'xvz1evFS4wEEPTGEFPHBog',
        secret: 'kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw',
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return crypto
            .createHmac('sha1', key)
            .update(base_string)
            .digest('base64')
    },
})

const request_data = {
    url: 'https://api.twitter.com/1/statuses/update.json?include_entities=true',
    method: 'POST',
    data: { status: 'Hello Ladies + Gentlemen, a signed OAuth request!' },
}

// Note: The token is optional for some requests
const token = {
    key: '370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb',
    secret: 'LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE',
}

request(
    {
        url: request_data.url,
        method: request_data.method,
        form: oauth.authorize(request_data, token),
    },
    function(error, response, body) {
        // Process your data here
    }
)

Or if you want to send OAuth data in request's header:

request(
    {
        url: request_data.url,
        method: request_data.method,
        form: request_data.data,
        headers: oauth.toHeader(oauth.authorize(request_data, token)),
    },
    function(error, response, body) {
        // Process your data here
    }
)

Work with jQuery.ajax (Browser):

Caution: Please make sure you understand what happens when using OAuth protocol on the client side here

// Initialize
const oauth = OAuth({
    consumer: {
        key: 'xvz1evFS4wEEPTGEFPHBog',
        secret: 'kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw',
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
        return CryptoJS.HmacSHA1(base_string, key).toString(CryptoJS.enc.Base64)
    },
})

const request_data = {
    url: 'https://api.twitter.com/1/statuses/update.json?include_entities=true',
    method: 'POST',
    data: { status: 'Hello Ladies + Gentlemen, a signed OAuth request!' },
}

// Note: The token is optional for some requests
const token = {
    key: '370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb',
    secret: 'LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE',
}

$.ajax({
    url: request_data.url,
    type: request_data.method,
    data: oauth.authorize(request_data, token),
}).done(function(data) {
    // Process your data here
})

Or if you want to send OAuth data in request's header:

$.ajax({
    url: request_data.url,
    type: request_data.method,
    data: request_data.data,
    headers: oauth.toHeader(oauth.authorize(request_data, token)),
}).done(function(data) {
    // Process your data here
})

.authorize(/_ options _/)

  • url: String
  • method: String default 'GET'
  • data: Object any custom data you want to send with, including extra oauth option oauth_* as oauth_callback, oauth_version...
  • includeBodyHash: Boolean default false set to true if you want oauth_body_hash signing (you will need to have define the body_hash_function in most cases - for HMAC-SHA1 Oauth signature method, the body_hash_function should return a SHA1 hash).
const request_data = {
    url: 'https://bitbucket.org/api/1.0/oauth/request_token',
    method: 'POST',
    data: { oauth_callback: 'http://www.ddo.me' },
}

.toHeader(/_ signed data _/)

Convert signed data into headers:

$.ajax({
    url: request_data.url,
    type: request_data.method,
    data: request_data.data,
    headers: oauth.toHeader(oauth.authorize(request_data, token)),
}).done(function(data) {
    // Process your data here
})

Init Options

const oauth = OAuth(/* options */)
  • consumer: Object Required your consumer keys
{
  key: <your consumer key>,
  secret: <your consumer secret>
}
  • signature_method: String default 'PLAINTEXT'
  • hash_function: Function if signature_method = 'PLAINTEXT' default return key
  • body_hash_function: Function default to hash_function
  • nonce_length: Int default 32
  • version: String default '1.0'
  • parameter_seperator: String for header only, default ', '. Note that there is a space after ,
  • realm: String
  • last_ampersand: Bool default true. For some services if there is no Token Secret then no need & at the end. Check oauth doc for more information

oauth_signature is set to the concatenated encoded values of the Consumer Secret and Token Secret, separated by a '&' character (ASCII code 38), even if either secret is empty

Notes

  • Some OAuth requests without token use .authorize(request_data) instead of .authorize(request_data, {})
  • Or just token key only .authorize(request_data, {key: 'xxxxx'})
  • Want easier? Take a look:

Client Side Usage Caution

OAuth is based around allowing tools and websites to talk to each other. However, JavaScript running in web browsers is hampered by security restrictions that prevent code running on one website from accessing data stored or served on another.

Before you start hacking, make sure you understand the limitations posed by cross-domain XMLHttpRequest.

On the bright side, some platforms use JavaScript as their language, but enable the programmer to access other web sites. Examples include:

  • Google/Firefox/Safari extensions
  • Google Gadgets
  • Microsoft Sidebar

For those platforms, this library should come in handy.

License

MIT

oauth-1.0a's People

Contributors

asharpe-squiz avatar bitdeli-chef avatar bryant1410 avatar casperengl avatar ddo avatar dependabot[bot] avatar dinoboff avatar francescosalvi avatar gitter-badger avatar jasonmerino avatar johnstonbl01 avatar kaycebasques avatar paulrutter avatar peterblazejewicz avatar plant99 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oauth-1.0a's Issues

RSA-SHA1 support

What is the timeframe for RSA-SHA1 support ? I see the code says 'Coming Soon...' ..?

Anything we can do to help/contribute ?

"Duplicate timestamp/nonce combination, possible replay attack. Request rejected."

Got Duplicate timestamp/nonce combination, possible replay attack. Request rejected. while trying to authorize in headers, which is the only thing that this API accepts.

function getOAuth(consumer_key, consumer_secret) {
	return OAuth({
		consumer: {
			key: consumer_key,
			secret: consumer_secret
		},
		signature_method: "HMAC-SHA1",
		hash_function: function(base_string, key) {
			return crypto.createHmac("sha1", key).update(base_string).digest("base64")
		}
	})
}

// ...

router.get("/api/me", function(req, res) {
	if (!req.query.key || !req.query.secret) {
		return res.status(400).end()
	}

	const oauth = getOAuth(req.query.key, req.query.secret)

	const request = {
		url: "<redacted>",
		method: "GET"
	}

	axios.get(request.url, {
		headers: oauth.toHeader(oauth.authorize(request))
	})
	.then(function(response) {
		res.send(response.data)
	})
	.catch(function(err) {
		res.send(err.response.data)
	})
})

Body hash should be generated using SHA1

Body Hash signature currently uses hash_function option, typically a "HMAC-SHA1" signature function instead of "SHA1".

It should instead use a body_hash_function option, default body_hash_function to the hash_function option, deprecate defaulting to hash_function in version <3.0.0 and remove the default in v3.0.0.

Reference:

According to RFC5849 port number must be excluded from base string if it is the default

3.4.1.2. Base String URI
(...)
3. The port MUST be included if it is not the default port for the
scheme, and MUST be excluded if it is the default. Specifically,
the port MUST be excluded when making an HTTP request [RFC2616]
to port 80 or when making an HTTPS request [RFC2818] to port 443.
All other non-default port numbers MUST be included.

POST with JSON body

Sorry if this is the wrong place for this kind of questions...

Is there any sample on using it as a post with json body?

Thank in advance

Working with Etsy Api - Example?

Hello, I am trying to use your OAuth library, with Etsy Api to manage products. This is going to be used for personal use, so security is not an issue.

Trying to figure out how I can get a request token, and store it for signed requests.
Can you please show a client side example (preferably etsy) on how to authenticate with oauth, and then save credientials for future requests?

THANKS IN ADVANCE

https://www.etsy.com/developers/documentation/getting_started/oauth

Easy-Jquery ETA?

Thx for code!

Any ETA on the version listed as:

Want easier? Take a look: jquery: soon
Here, under "Notes"

I'm developing a new project, and just wondering if i should wait for it.

Multiple values per parameter are not supported

When using multiple values per parameter, the oAuth sign is not correct.
The codebase does not take multiples into account, and treats it as 1 String.

oauth.authorize({ 
  formKey: ["formvalue1", "formvalue2"] 
});

I have debugged (and fixed) this, and will create a pull request for it.

Same oauth_nonce, add a way to seed the getNonce function

Hi, my team is currently experiencing an unexpected behavior when bots try to index our page, this is because some bots always generate the same value when you call:
Math.random();

So when this library tries to generate an oauth_nonce It will always be the same because this line use the number generated by Math.random

result += word_characters[parseInt(Math.random() * word_characters.length, 10)];

Maybe we should add a way to seed the randomness of this function? What do you think?

oauth_verifier is missing

I'm not sure if this library is supposed to work only for the first leg of the Oauth1.0 flow (something like "/.../oauth1/Request"), but after the consumer receives the temporary tokens and being redirected to the provider login page, it receives back an oauth_token and oauth_verifier.
The oauth_verifier must be part of the last request (something like "/...oauth1/Access") in order to receive the token and token_secret used to access protected resources.

I had to modify the library to include this oauth_verifier token for the third leg of the Oauth1 flow to make it work.

Anybody else in my situation? Should I make a PR?

oauth_signature does not match expected value

An error response;

oauth_signature does not match expected value

is responded from the Tumblr v2 API when I try to get access token from the API.

Is this known problem?

This is the code I use for Chrome Extension:

var requestToken = Observable.fromNodeCallback(function (data, cb) {
  var oauth = OAuth({
    consumer: {
      public: data.key,
      secret: data.secret
    }
  });
  var request = {
    url: 'https://www.tumblr.com/oauth/request_token',
    method: 'GET',
    data: {
      oauth_callback: 'https://example.com/'
    }
  };
  superagent
  .get(request.url)
  .set(oauth.toHeader(oauth.authorize(request)))
  .end(cb);
});

var authorize = Observable.fromCallback(function (data, cb) {
  var url = 'https://www.tumblr.com/oauth/authorize?oauth_token=' + data.oauth_token;
  chrome.tabs.create({ url: url, active: true }, cb);
});

var verifyToken = Observable.fromCallback(function (currentTabId, cb) {
  chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (currentTabId === tabId && changeInfo.url && !/^https:\/\/www\.tumblr\.com\/oauth\/authorize?.*/.test(changeInfo.url)) {
      chrome.tabs.remove([ tabId ]);
      var matched = changeInfo.url.match(/(oauth_token)=([a-zA-Z0-9]+).+(oauth_verifier)=([a-zA-Z0-9]+)#_=_$/);
      cb(_.isArray(matched) ? { oauth_token: matched[2], oauth_verifier: matched[4] } : null);
    }
  });
});

var fetchToken = Observable.fromNodeCallback(function (data, cb) {
  var oauth = OAuth({
    consumer: {
      public: data.key,
      secret: data.secret
    }
  });
  var token = {
    public: data.oauth_token,
    secret: data.oauth_token_secret
  };
  var request = {
    url: 'https://www.tumblr.com/oauth/access_token',
    method: 'GET',
    data: {
      oauth_verifier: data.oauth_verifier
    }
  };
  superagent
  .get(request.url)
  .set(oauth.toHeader(oauth.authorize(request, token)))
  .end(cb);
});

var authorized$ = Observable.combineLatest(submitted$, tokensFetched$)
.flatMap(function (results) {
  var data = results[1];
  return authorize(data);
})
.flatMap(function (tab) {
  return verifyToken(tab.id);
})
.flatMap(function (data) {
  return setStorage(data);
})
.flatMap(function () {
  return getStorage();
})
.flatMap(function (data) {
  return fetchToken(data);
});

Update from 2.1.0 to 2.1.1 breaks signature

Hello
first of all, thanks for the useful library.
Since I updated the dependency in my project (integrates with the Beatport API, 3-legged) and it passed from 2.0.0 to 2.2.0, I get "Invalid OAuth signature. Expected value ..." when performing a Request Token request.

Since nothing has changed in the code/environment/configuration, I was wondering if you could give me any hint about what major changes that were introduced in this version that might need my attention

The affected request uses POST and .toHeader()

Thank you!

oauth_body_hash is missing

Hi,

After sending a post request with a json payload, I see that the request was sent without oauth_body_hash in the Authorization header. Here is the code:

var request = require('request');
var crypto = require('crypto');
var OAuth = require('oauth-1.0a');

 var oauth = OAuth({
      consumer: {
        key: KEY,
        secret: SECERET
      },
      signature_method: 'HMAC-SHA1',
      hash_function: function (base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
      }
    });

    var request_data = {
      url: http://example.com/api,
      method: 'POST',
      data: {
          key: "value"
      } 
    };

    let headers = oauth.toHeader(oauth.authorize(request_data))
    headers = Object.assign({}, headers, {
      'Content-Type': "application/json+1"
    })

    request({
      url: request_data.url,
      method: request_data.method,
      body: JSON.stringify(request_data.data),
      headers
    }, function (error, response) {
        //further code
    }); 

Fix typings

Make realm parameter in options optional.

Validate existing oauth signature

I have the requirement to validate an oauth signature, I've had a look through the module but couldn't see a way to do this.

I've identified a couple of changes that would support this feature but wanted to check if this was already possible.

getting invalid signature in response

Hi i tried OAuth 1.0a with https module. but getting invalid signature as response.i tried with same credentials in postman its working n i'm getting results too. and if i hardcode oAuth header generated from postman able to get response. but not with module genrated Authorization header.
I mentioned the code below. please help me out.

var OAuth   = require('oauth-1.0a');
var crypto  = require('crypto');
var https = require('https');
/*OAuth initialization*/

 var oauth = OAuth({
    consumer: {
        key: 'key',
        secret: 'secret'
    },
    signature_method: 'HMAC-SHA1',
    hash_function: function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
 });
  var request_data = {
    url: 'url',
    method: 'POST',
    data: {
    //parameters here
    }
  };
  var token = {
	key: 'key',
	secret: 'secret'
  };
  var Head = oauth.toHeader(oauth.authorize(request_data, token)); 
  var Header = {};
  Header["Authorization"] =Head.Authorization;
  Header["Accept"]= "application/json";
  Header['Content-Type']="application/json";
  var options = {
    host: 'url',
    path: 'path',
    method: 'POST',
    headers: Header
  };
  var request = https.request(options, function(response) {
    response.setEncoding('utf-8');
    var responseString = '';
    response.on('data', function(data) {
      responseString += data;
    });
    response.on('end', function() {
      console.log(responseString);//returning invalid signature
    });
  });
  request.write(JSON.stringify(request_data.data));
  request.end();

});

TypeError: Cannot read property 'toUpperCase' of undefined

Anyone getting this? TypeError: Cannot read property 'toUpperCase' of undefined. Not sure what i am doing wrong. my code -

request({
url: hook.params.query.url,
method: hook.params.query.method,
form: modelData.data,
headers: oauth.toHeader(oauth.authorize(modelData.data, token))
}, function(error, response, body) {
// Process your data here
});

How to: callback URL

I'm using oauth-1.0a with wordpress and I just want to know how to get oauth.authorize to include a callback URL. Do I define it in the request object that I pass to oauth.authorize()? What parameters, then, do I use?

The Oauth Bible says that for 3 legged authorization callback urls can be used, so it's not a wordpress specific thing.

Invalid signature issue - 401 error

HI, I'm fairly new to coding so forgive my ignorance if this is not supposed to go here. But I am stuck on how to rectify this issue considering on postman I can get back data but I guess I am not writing my code properly? Any help.

This is my code:

componentDidMount() {
  const oauth = OAuth({
    consumer: {
      key: 'XXXXX',
      secret: 'XXXXX',
      signature_method: 'HMAC-SHA1',
      hash_function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
      }
    },
  });

  const request_data = {
    url: 'http://localhost:8888/wp-json/wc/v2/products/28/variations',
    method: 'GET',
  };

  const token = {
    key: 'XXXXX',
    secret: 'XXXXX',
  };

  fetch(request_data.url, {
    method: request_data.method,
    headers: oauth.toHeader(oauth.authorize(request_data, token))
  })
    .then(response => response.json())
    .then(response => {
      this.setState({
         products: response
      })
   })
}

TypeScript definitions should not have implicit any

Thanks for create this module and for including a d.ts file!

The definition for BodyHashFunction is missing types for its arguments, though. This causes tsc to complain, when noImplicitAny is turned on.

This should be easy to fix:

export type BodyHashFunction = (base_string: string, key: string) => string

I would be happy to provide a PR. Just let me know.

Thanks again!

Example for bitbucket

It seems that I cannot get a request_token for bitbucket oauth1.
I tried to follow their documentation and the example you have for Etsy but it is still complaining about the oauth_callback missing.
Do you have any example targeting the bitbucket api?

Sending RSA-SH1 encoded requests?

Wondering if it's possible to use RSA-SH1 with this library. The example you've provided for request (Node.js) uses HMAC:

var oauth = OAuth({
    consumer: {
        key: 'xvz1evFS4wEEPTGEFPHBog',
        secret: 'kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw'
    },
    signature_method: 'HMAC-SHA1',
    hash_function: function(base_string, key) {
        return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
});

To make it work with RSA, I've tried changing the OAuth.prototype.getSigningKey function to return an RSA private key, and used the following init:

var oauth = OAuth({
    consumer: {
        key: inputData.consumerKey,
        secret: inputData.consumerSecret
    },
    signature_method: 'RSA-SHA1',
    hash_function: function(base_string, key) {
      var buffer = new Buffer(base_string);
      var encrypted = crypto.privateEncrypt(key, buffer);
      return encrypted.toString("base64");
    }
});

But no luck so far. Just wondering if RSA is possible with this library's code - or am I barking up the wrong tree?

Reducing lib size

Thanks for open-sourcing this--really useful stuff.

I'm noticing that while unminified oauth-1.0a.js is just 7 KB, including this library in my minified Webpack bundle adds 60 KB in total to the bundle size. This is almost entirely due to the transitive dependency on CryptoJS.

Would there be any interest in either carving our a smaller crypto dependency (oauth-1.0a.js only uses three functions from CryptoJS) or providing a means by which to inject the crypto dependency such that clients could package their own smaller crypto libraries?

Cheers.

401 Not Authorized on POST to Tumblr

Hey there! I'm getting 401 error when trying to do an edit on a post for my blog... could you tell me why?

var utils = require('./utils.js');
var removeTagFromPosts = utils.removeTagFromPost;

var request_data = {
    url: 'https://api.tumblr.com/v2/blog/gaming-thrones.tumblr.com/posts/?tag=gaming%20thrones',
    method: 'GET'
};

utils.request(request_data, function(error, response, body) {
    var body = JSON.parse(body);
    console.log(body);
    utils.removeTagFromPosts('gaming thrones', body.response.posts);
});

var OAuth = require('oauth-1.0a');
var request = require('request');

var oauth = OAuth({
    consumer: {
        public: 'public', // this is set to my public key
        secret: 'secret'  // this is set to my secret key
    },
    signature_method: 'HMAC-SHA1'
});

var token = {
    public: 'public', // this is set to my public key
    secret: 'secret'  // this is set to my secret key
};

function requestHelper(requestObj, callback) {
    var req = {
        url: requestObj.url,
        method: requestObj.method,
        form: requestObj.data,
        headers: oauth.toHeader(oauth.authorize(requestObj, token))
    }
    request(req, callback);
}

function removeTagFromPosts(tag, posts) {
    for (post of posts) {
        console.log('Removing ' + tag + ' from post with ID ' + post.id); 
        console.log('Current tags: '+ post.tags);
        post.tags = post.tags.filter(function(value) { return value != tag });
        console.log('New tags: '+ post.tags);
        console.log('Sending post data:', post);
        requestHelper({
            url: 'http://api.tumblr.com/v2/blog/gaming-thrones.tumblr.com/post/edit',
            method: 'POST',
            data: post,
        }, function(error, response, body) {
            if (!error) {
                console.log('post updated!', response);
            } else {
                console.log(body);
            }
        });
        return;
    }
}

module.exports = {
    removeTagFromPosts: removeTagFromPosts,
    request:requestHelper
}

Authorized request example?

Hi, I'm using your library(with jQuery.ajax in the browser) to authenticate with a wordpress site(WP-API; the client and the site are on the same domain, different directories) and I've done the authentication part up to the point where I get the oauth_token and oauth_token_secret. My problem is that I'm not really sure how to make the authenticated request that actually gets the protected resources - I seem to always get a json_not_logged_in error. Is that something this library can handle or I should use something else? I checked out "oauth-request" but I'm not sure how to use it without node.js. Any help would be super appreciated!

Using with Fetch

I am using this project with Fetch with a custom OAuth Provider using Drupal. Add to documentation if you think it could be useful for others.

const url = "http://d8.epicureans.in/node/1?_format=json"
  const oauth = OAuth({
      consumer: {
          public: 'my_key',
          secret: 'my_secret'
      },
      signature_method: 'HMAC-SHA1'
  });
  const request_data = {
      url: url,
      method: 'GET'
  };
  return fetch(url, {
  headers: {...oauth.toHeader(oauth.authorize(request_data))}
}).then(function(response) {
             console.log(response)
             if (response.status !== 200) {
               console.log('Looks like there was a problem. Status Code: ',   response.status);
               return;
             }
             return response.json()
           })

HMAC-SHA256 Signature method

All our stuff runs on HMAC-SHA256 - it would be real nice to be able to talk to it with node...I've attempted an implementation in my fork but something is just not coming together...

Invalid Signature - provided signature does not match

Here is my code. I am trying my angularJS app to interact with the Woocommerce API over HTTP (NOT HTTPS).

`var oauth = OAuth({
consumer:{
public: ck,
secret: cs
},
signature_method: 'HMAC-SHA1',
last_ampersand: false
});

var request_data = {
  url: url,
  method: 'GET'
};

var token = {
  public: '370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb',
  secret: 'LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE'
};

$http({
  url: request_data.url,
  method: request_data.method,
  params: oauth.authorize(request_data, token)
}).then(function(data){
  console.log(data);
}, function(error){
  console.log(error);
})`

I always get the following error.

errors: [ { code: "woocommerce_api_authentication_error", message: "Invalid Signature - provided signature does not match" } ]

Any help is highly appreciated.

No oauth parameters supplied?

I've tried exactly the same credentials at postman and works fine so i guess the problem should be here:

let request_data = {
            url: url,
            method: 'GET',
            data: {
              oauth_verifier: oauthVerifier,
              oauth_token: oauthToken,
              oauth_secret: oauthSecretToken,
              oauth_version: "1.0"
            }
          };
          request({
            url: request_data.url,
            method: request_data.method,
            form: oauth.authorize(request_data)
          }, function(err, res, body) {
            if (err) {
              console.log(err);
            }
            console.log(res.statusCode); //400 :(
          });

All the variables are correct so i don't know where the problem could be, any idea? :S

Base String is incorrect if url contains encoded &

Consider the following request with an encoded & (%26) in a parameter value:
http://www.mysite.com?myparam=valuepart1%26valuepart2

The call:

OAuth({consumer: { public: 'public', secret: 'secret' }}).getBaseString({data: {}, method: 'GET', url : 'http://www.mysite.com?myparam=valuepart1%26valuepart2'}, {});

Results in the base string:

GET&http%3A%2F%2Fwww.mysite.com&myparam%3Dvaluepart1%26valuepart2%3Dundefined

This is incorrect because the parameter value part after the & is seen as a separate parameter. The correct base string is (use e.g. http://oauth.googlecode.com/svn/code/javascript/example/signature.html):

GET&http%3A%2F%2Fwww.mysite.com%2F&myparam%3Dvaluepart1%2526valuepart2

This happens because deParam does a decodeURIComponent from the entire string and then splits on &. deParam should perform a separate decode of the key and values.

    OAuth.prototype.deParam = function(string) {
      var arr = string.split('&');
      var data = {};

      for(var i = 0; i < arr.length; i++) {
        var item = arr[i].split('=');
        data[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);
      }
      return data;
    };

401 error - invalid oauth signature

Hi there I am getting 401 errors sometimes when I use the following code.
The error in the log is InvalidSignatureException. I have also found that whenever the signature has + in it, then I am getting this error. Please let me know if the code below is not correct.

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

const createHmac = require('create-hmac');
const OAuth = require('oauth-1.0a');

@component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
constructor(private http: HttpClient) { }

ngOnInit() {
const oauth = OAuth({
consumer: {
key: 'XXXXX',
secret: 'XXXXXX'},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return createHmac('sha1', key).update(base_string).digest('base64');
}
});

const request_data = {
  url: 'XXXXXX',
  method: 'GET',
};

const auth = oauth.authorize(request_data);
let headers = new HttpHeaders();
headers = headers.set('Authorization', 'OAuth oauth_consumer_key="' + auth.oauth_consumer_key
  + '", oauth_nonce="' + auth.oauth_nonce
  + '", oauth_signature="' + auth.oauth_signature
  + '", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' + auth.oauth_timestamp
  + '", oauth_version="1.0"').set('content-type', 'text/plain').set('accept', 'text/plain');
console.log(headers);
this.http.get(request_data.url, { headers: headers },
).subscribe(res => console.log(res));

}
}

Signature Not Handling Complex Object Structure

Hi,

I am integrating with an API which uses oauth1 authentication.
I am able to perform get and post request.
However when I try to include Customer object in my below payload, the api reject with Authorization error probably due to signature issue.
I observe that authorize function returns empty Customer like &Customer=&

const visitDate = moment().tz('Australia/Sydney').add(2, 'h').format('YYYY-MM-DDTHH:mm:ss');
const bookingInfo = {
Covers: 1,
Duration: 60,
Status: 1,
Tables:24102,
VisitDateTime: visitDate,
Customer: {
"Email": "[email protected]",
"Title": "Mr",
"FirstName": "Zarni",
"Surname": "Aung",
"MobileNumber": "00112233"
}
};
Would you encounter such issue before?

Base string incorrect for array type GET query string

It seems that array type GET query strings aren't quite supported.

e.g.

// request_data.data
{ 
  filter: [ { attribute: 'updated_at', from: '2017-05-10 00:00:00' } ],
  limit: 100,
  page: 1 
}

If you url encode this with something like qs, then you would get

filter%5B0%5D%5Battribute%5D=updated_at&filter%5B0%5D%5Bfrom%5D=2017-05-10%2000%3A00%3A00&limit=100&page=1

or in other words

filter[0][attribute]=updated_at&filter[0][from]=2017-05-10 00:00:00&limit=100&page=1

Which is a valid query string.

However, when the module is getting the Base string from this, the parameter string comes out like so

filter%3D%255Bobject%2520Object%255D%26filter%25255B0%25255D%25255Battribute%25255D%3Dupdated_at%26filter%25255B0%25255D%25255Bfrom%25255D%3D2017-05-10%252000%253A00%253A00%26limit%3D100%26page%3D1

Which decodes to

filter=[object Object]&filter[0][attribute]=updated_at&filter[0][from]=2017-05-10 00:00:00&limit=100&page=1

So as you can see it is nearly correct but the filter=[object Object]& breaks it.
Is there some other way I should be passing in the filter array to make this work like qs?
If I omit the filter parameter, then the signature works fine with the other params.

Hopefully I've explained myself well enough, thanks

If you are wondering, the filters in this format are expected by Magento's REST API
http://devdocs.magento.com/guides/m1x/api/rest/get_filters.html

Doesn't seem to handle "realm" properly.

The method we're calling requires the use of the Oauth realm, and we tried specifying that in the request_data.data map we sent do the oauth.authorize method. This "almost worked", but not quite.

Issues:

  1. The realm was included in the string to sign, but that should not be so.
  2. The realm was properly included in the OAuth header string, but it was last (per alphabetical order) but realm is required to be first in the header.

We worked around for now by NOT specifying the realm in the data, and instead, manually adding it before use...

var request_data = {    
    url: 'http://www.example.com',
    method: 'GET'
};

// generate the auth header WITHOUT any realm.
var headers = oauth.toHeader(oauth.authorize(request_data, token));
// manually add the realm after the fact:
headers.Authorization = headers.Authorization.replace("OAuth ", 'OAuth realm="12345",');

request({    
    url: request_data.url,
    method: request_data.method,
    headers: headers
}, function(error, response, body) {    
    console.log(body);
});

"oauth signature does not match" with "WP-API/OAuth1"

Hello,

I have already created an issue here: WP-API/OAuth1#146

In short your library is using a different key to what the WordPress plugin is (only secret without key). Could you please have a look and see if there is anything you could fix?

Thank you for the great plugin and work,
best,

Lukas

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.