Oct 8, 2010

xAuth lib: OAuth made easy

Hi all,

Nowadays, important sites on web are growing their presence in mobile space. As usual, a quick way to go in this direction is releasing mobile versions of their sites. On the other hand, they also use to provide means so third-party sites and apps can access their content and services. For instance, many sites (or platforms), e.g., Google, Yahoo, Facebook, Twitter, etc, provide APIs, so that developer can build their products that rely on content from them.

To start accessing any content or service from one of those sites, you first need to authenticate with it. The site needs to recognize you so it can open their doors for you. The type of authentication may vary depending on each site. It is commom to encounter with Http Basic Auth, which is very easy to work with. However, most services are shifting to OAuth. A more secure auth mechanism that also avoids third-party sites have access to user's credentials. Recently, Twitter turned off its Http Basic Auth, to support only OAuth. Some sites still work with both, but it is matter of time so they keep only OAuth.

Due to some aspects of OAuth, its pure implementation is not feasible for desktop and mobile apps. This is related to a spec flow that demands your app to be redirected forth/back to/from a login page. It is kind of complicated to accomplish that in a mobile app, for instance. To avoid this step, they created xAuth, which is same as OAuth, but the login page flow.

An OAuth request is quite more complicated to perform, since it requires a signature for the request, which uses some hash algoritms and encoders. To now more about it, click here.

In my Twitter API ME project, I had to implement it, since as I previously said, Twitter turned off Http Basic Auth. However, my xAuth implementation was designed to be reused by other apps and frameworks. So, if you are looking for xAuth lib for your app, you are at the right place. So, to start it up, download the latest version of Twitter API ME at www.twitterapime.com.

Below I will put some code snippets that demonstrate how to get authenticated to Twitter and then post a tweet. After downloading the API, you will need to obtain your app's OAuth keys: consumer key and secret. They will be used to produce that signature I mentioned ealier. Those keys are provided by the site you want to connect with, after a quick subscription. Let's show some code:

01. HttpRequest req = new HttpRequest("https://api.twitter.com/oauth/access_token");
02. req.setMethod(HttpConnection.POST);

 
03. XAuthSigner signer = new XAuthSigner("", "");
04. signer.signForAccessToken(req, "", "");

05. try {
06.     HttpResponse resp = req.send();
07.     if (resp.getCode() == HttpConnection.HTTP_OK) {
08.        Token accessToken = Token.parse(resp.getBodyContent());

09.        req.close();

10.        req = new HttpRequest("http://api.twitter.com/1/statuses/update.xml");
11.        req.setMethod(HttpConnection.POST);
12.        req.setBodyParameter("status", "");
13.        req.setSigner(signer, accessToken);

14.        resp = req.send();
15.     }
16. } catch (IOException e) {
17.     e.printStackTrace();
18. } finally {
19.     try {
20.         req.close();
21.     } catch (IOException e) {}
22. }

Basically what we do is to sign each request, using XAuthSigner class, as we see in the lines 4 and 13. As soon as you get authenticated, you will obtain your access token (line 8). From this point on, every request will be signed using your keys and token. This token, in turn, can be stored for further use. It avoids requesting user's credentials next time and skip auth step.

I recommend before trying to access any site using xAuth, that read its documentation first, so you can see whether they require an additional procedure to work with xAuth. I am mentioned that, because Twitter, for instance, demands us to send an e-mail to them requesting privileges to use xAuth in our apps. Otherwise, it will not work. So be aware of that.

So, that's all guys! I hope it be useful for all of you.

See you in the next post...

8 comments:

Unknown said...

hi i m blackberry devloper yeah that's very good code but in the code i found a bug when store a token and send a request using that token it gives 403 response code means plz sort out this issue
thanx in advance

here is my code
req= new HttpRequest("http://api.twitter.com/1/statuses/update.xml");
XAuthSigner signer = new XAuthSigner(consumer key,scret );
try
{
req.setMethod(HttpConnection.POST);
String strTweet = tweet + " " + des;
if (strTweet.length() < 138)
{
req.setBodyParameter("status",strTweet );
} else
{
req.setBodyParameter("status",strTweet.substring(0, 137)+".." );
}
req.setBodyParameter("status", strTweet);
Vector vecdata=(Vector)store.getContents();

Token accessToken1=(Token)vecdata.elementAt(1);
req.setSigner(sign, accessToken1);
final HttpResponse resp = req.send();

if (resp.getCode() == HttpConnection.HTTP_OK)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Twetted Sucessfully"+resp.getCode());
}
});
}
else
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
Dialog.alert("Tweet not posted"+resp.getCode());
}
});
}
}

Nikhil said...

hey i am using this following code but i am getting 401 error... :( please help

HttpRequest req = new HttpRequest("https://api.twitter.com/oauth/access_token");

req.setMethod(HttpConnection.POST);

XAuthSigner signer = new XAuthSigner(conKey, conSec);
signer.signForAccessToken(req, user, pass);
try {
HttpResponse resp = req.send();
if (resp.getCode() == HttpConnection.HTTP_OK)
{
Token accessToken = Token.parse(resp.getBodyContent());
req.close();
add(new LabelField("3"));
req = new HttpRequest("http://api.twitter.com/1/statuses/update.xml");
req.setMethod(HttpConnection.POST);
req.setBodyParameter("status", "Message");
add(new LabelField("13"));
req.setSigner(signer, accessToken);
add(new LabelField("4"));
resp = req.send();
}
else { add(new LabelField("1234"));add(new LabelField(resp.getCode()+""));}

} catch (IOException e) {
e.printStackTrace();
add(new LabelField("exception: " +e.getMessage()));
}
catch(Exception e){add(new LabelField(e.getMessage()));}finally {
try {
req.close();
} catch (IOException e) { add(new LabelField("exception1: " +e.getMessage()));}
}

Ernandes Mourão Júnior said...

Check out if your device's current date/time is not wrong. This may cause this kind of error.

gunj said...

i m using twitter api 1.6 in blackberry 6.0 but i got native method error.any one knows about that please reply

Satish said...

hi i am blackberry developer that's very good code but in the code i found a bug when store a token and send a request using that token it gives "net.rim.device.cldc.io.ssl.TLSIOException"

Prasanth P said...

How do access permission to my API, In twapime.com site, they are asking to send mail to api@twitter.com. What is does meant actually.

Anonymous said...

In this example someone works? I try but not work for me

Anonymous said...

Where can i find this code at? Is your source somewhere on github?