GET method with Twitter OAuth Authentication cannot perform correctly?
Hi there!
I'm trying to test a twitter's OAuth API with oauth.js and sha1.js.
Thanks to your past post, I can establish an OAuth authentication.
An my new tweet can be posted like this,
var accessor = {
consumerSecret: myConsumerSecret,
tokenSecret: myAccessTokenSecret
};
var message = {
method: "POST",
action: "https://api.twitter.com/1/statuses/update.json",
parameters: {
oauth_signature_method: "HMAC-SHA1",
oauth_consumer_key: myConsumerKey,
oauth_token: myAccessToken,
status:"I'm tweeting!" //--- post a new tweet.
}
};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var xhr = Ti.Network.createHTTPClient();
xhr.open("POST", message.action, false);
xhr.send( OAuth.getParameterMap(message.parameters) );
It perfectly works.
POST method API (new tweet etc.) like the above seems to work correctly.
However, it doesn't work at all when I similarly try the GET method (getting user's timeline etc.). I have changed it simply as follows,
var accessor = {
consumerSecret: myConsumerSecret,
tokenSecret: myAccessTokenSecret
};
var message = {
method: "GET",
action: "https://api.twitter.com/1/statuses/home_timeline.json",
parameters: {
oauth_signature_method: "HMAC-SHA1",
oauth_consumer_key: myConsumerKey,
oauth_token: myAccessToken,
count: 200 //--- tweets count to get.
}
};
OAuth.setTimestampAndNonce(message);
OAuth.SignatureMethod.sign(message, accessor);
var ACTION_URL = OAuth.addToURL(message.action, message.parameters);
var xhr = Ti.Network.createHTTPClient();
xhr.open("GET", ACTION_URL, false);
xhr.send(null);
This http status code always returns "401" (means authentication error on server). it won't return "200". Is there a wrong part somewhere?
In Addition, when I put out "ACTION_URL" by Ti.API.debug, and copy it into Safari's address field, Safari shows correct JSON string with response status "200".
"ACTION_URL" has something like this,
http://api.twitter.com/1/statuses/home_timeline.json?oauth_consumer_key=
Ie6GBSRMyQVotY5uT7941g&oauth_signature_method=HMAC-SHA1&
oauth_token=58789810-NU5o9qUCWhJp0EOral4NS99MjrNSKNc7wbmuidsf&
count=200&oauth_timestamp=1285522222&oauth_nonce=Wma20tH&
oauth_signature=%2Fh8YWptNJWU6Cji%2B0FIOPodWK4s%3D
Strange points are,
- POST method performs perfectly, but GET with OAuth does not work.
- Same GET URL works in Safari though it doesn't perform in Titanium.
How can I work it like the browser?
Any answers are appreciated!
6 Answers
-
Ok I found it, just in case anyone have the same problem. Here's my solution. I basically just concat all the necessary parameters to the URL and then GET that url like this:
var parameterMap = OAuth.getParameterMap(message.parameters); for (var p in parameterMap) { Ti.API.debug(p + ': ' + parameterMap[p]); pUrl += "&" + p + "=" + parameterMap[p]; } var client = Ti.Network.createHTTPClient(); client.open("GET", pUrl, false); client.send();
and call it like this
oAuthAdapter.get("http://api.twitter.com/1/statuses/home_timeline.json?true=1");
I need to add
true=1
so that I can start the param with &.Hope it helps :)
-
maybe this can help you:
~~~
Ti.include('sha1.js');
Ti.include('oauth.js');
Ti.include('oauth_adapter.js'); // i get the oauth_adapter from http://code.google.com/p/oauth-adapter//*
Sendet den Tweet zu Twitter /
var send_to_twitter = function(message){
var oAuthAdapter = new OAuthAdapter(VRM_CONFIG['TWITTER_SECRETKEY'], //Secret Key VRM_CONFIG['TWITTER_CONSUMERKEY'], //Consumer Key 'HMAC-SHA1'); // load the access token for the service (if previously saved) oAuthAdapter.loadAccessToken('twitter'); //oAuthAdapter.send('http://twitter.com/statuses/update.json', { status: 'status_text', source: "twoot" }, 'Twitter', 'Published.', 'Not published.'); oAuthAdapter.send('https://api.twitter.com/1/statuses/update.json', [['status', message]], 'Twitter Message', 'Gesendet.', 'Nicht gesendet.'); // if the client is not authorized, ask for authorization. the previous tweet will be sent automatically after authorization if (oAuthAdapter.isAuthorized() == false) { // this function will be called as soon as the application is authorized var receivePin = function() { // get the access token with the provided pin/oauth_verifier oAuthAdapter.getAccessToken('http://twitter.com/oauth/access_token'); // save the access token oAuthAdapter.saveAccessToken('twitter'); }; // show the authorization UI and call back the receive PIN function Ti.API.info(oAuthAdapter.getRequestToken('http://twitter.com/oauth/request_token')); oAuthAdapter.showAuthorizeUI('http://twitter.com/oauth/authorize?' + oAuthAdapter.getRequestToken('http://twitter.com/oauth/request_token', [['oauth_callback', 'oob']]), receivePin); }
};
~~
-
Thank you for the reply.
Of course, I know oauth_adapter.js. That's a great job . I have read oauth_adapter.js, and understood how it works.
However, I think that oauth_adapter.js is written for POST-method Twitter API. Therefore, only the limited API can be called (status/update or status/destroy etc..).
But, APIs that I want to call is used with GET-method (for instance, statuses/home_timeline, statuses/friends_timeline, and statuses/user_timeline etc..).
Or, can I do with oauth_adapter.js?
Please tell me a detailed method if so.Thanks!
-
Hi I was wondering the same thing, couldn't get the method GET home_timeline to work. Can anybody help? I'm using oauth_adapter as well. POST works great, GET does not :(
-
I am having the exact same problem. I have narrowed it down.
The reason why it returns a 401 in Titanium is because it seems to be sending the request twice.
For the app I am building we have set up our own oAuth server and the debug output shows oAuth denies the request due to a duplicate replay attack. Meaning the same URL has been sent twice so it gets denied.
I cannot work out why this happens or how to fix it. It's basically holding up my app progress all because of this one issue.
If anyone has any suggestions I welcome them.
Thanks
-
Hope this helps everyone!
I almost killed myself searching a solution for this… but I finally found it. Use https://github.com/mogya/tm_twitter_api as it has the GET method too and then call it like this http://paste.pocoo.org/show/369523/