So this question has been asked several times, but I believe I've finally boiled down exactly what goes wrong here. I'm using the Yelp API with Angular, which requires OAuth 1.0a to access. Like most people doing this type of implementation, I'm using the following code:
.factory('YelpApi', ['$http',
function ($http) {
var randomString = function (length, chars) {
var result = '';
for (var i = length; i > 0; --i) {
result += chars[Math.round(Math.random() * (chars.length - 1))];
}
return result;
};
var retrieveYelp = function (name, callback) {
var method = 'GET';
var url = 'http://api.yelp.com/v2/search';
var params = {
callback: 'angular.callbacks._0',
ll: /* hidden */,
radius_filter: '3219',
oauth_consumer_key: /* hidden */, // consumer key
oauth_token: /* hidden */, //Token
oauth_signature_method: 'HMAC-SHA1',
oauth_timestamp: new Date().getTime(),
oauth_nonce: randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'),
term: name || 'food',
actionlinks: true
}; // end params
var consumerSecret = /* hidden */; //Consumer Secret
var tokenSecret = /* hidden */; //Token Secret
var signature =
oauthSignature.generate(
method,
url,
params,
consumerSecret,
tokenSecret,
{ encodeSignature: false }
);
// end signature
params['oauth_signature'] = signature;
console.log('inside yelpapi factory');
console.log('Term searched for: ' + params.term);
$http.jsonp(url, { params : params })
.then(callback, function(err) {
console.log('An error occured: ', err);
});
console.log("inside end of yelpapi factory");
}; // end retrieveYelp
return {
retrieveYelp: retrieveYelp
};
} // end function
]) // end factory
Here's the issue:
Using 'angular.callbacks._0'
as the callback makes it work the first time as it forces it to use the first callback, however breaks subsequent requests. You are actually supposed to use JSON_CALLBACK
to properly increment callbacks, however that breaks everything. The error generated by Yelp is "invalid signature". I believe this is caused by Angular not replacing JSON_CALLBACK
until after it's already encoded, thus causing the expected signature to be different than the actual one. I'm using this signature generator.
How could I get around this, ensuring Angular properly increments the callbacks while ensuring proper signature generation?