Tcoz Tech Wire

Discoursing on trends and technologies interesting to Tim Consolazio, sole proprietor of Tcoz Tech Services, specializing in Flash/Flex/Air, iPhone, Facebook, Twitter, and related technologies.

"Technology from an indie software developer's perspective".

Wednesday, June 3, 2009

TcozTwitter: A Twitter Client using Adobe Air and the Flex Mate Framework - Day 4 : Getting into Authentication

This is a continuation of a series of articles on my experiments with writing a Twitter desktop client using the Twitter API, the Mate Framework for Flex, and Adobe Air. Previous blog posts are here at Day 1, Day 2, and Day 3.

This time around, I started researching the dreaded topic, "Authentication". That is, in order to do anything really meaningful on behalf of a user, an application has to ask for your username and password, and one way or another, send it to Twitter for processing so that they can tell you "this is a known user, here's access to their stuff".

This is an interesting conundrum, since once you've installed a custom application and started using it, there's very little to prevent the application from taking your account information and sending it to a non-Twitter service. After all, you're just filling out a username and password form that isn't on the Twitter site, and clicking a button saying "sign in". The application could be sending that data anywhere. More tech-savvy users will know to use bad credentials first and monitor http calls carefully; if you see something not going to Twitter, something could be fishy.

There are social network apps and widgets out there that do this: IMHO YOU SHOULD NOT USE THEM. You are essentially giving your username and password to an unknown entity. Assurances aside, why take the risk? There is a better way...keep reading.

Let's assume that I'm not going to do anything nefarious with my own credentials. Unless I develop full-blown paranoia of some kind, I'm relatively certain that me-the-developer isn't going to compromise my Twitter account.

A visit to the Twitter API Wiki to review Twitter authentication reveals that there are two ways for an application to go about authenticating a user for access to their account-specific info: OAuth, and Basic Authentication. In brief layman's terms:

- Basic Authentication is a widely supported authentication mechanism involving sending the user's username and password encoded as Base64 via an HTTP POST. I won't get into what that means exactly here, suffice to say that it is a standard way of sending values to a web server, with those values represented in such a way that certain kinds of characters will not confuse or compromise the authentication mechanism. Such a transmitted string might look like "QWxhZGRpbjpvcGVuIHNlc2FtZQ==". While this may appear to be "secure" to the eye, since it's not the original string value (like your password), it isn't at all, because Base64 is easily decoded into it's original value. In other words, your credentials can be intercepted, decoded, and revealed.

Twitter allows the use of Basic Authentication, but they clearly don't like it. They're considering removing it in favor of OAuth. On their site, they say "We would like to deprecate Basic Auth at some point to prevent security issues but no date has been set for that."

So me, I'll use Basic Authentication will I'm dinking around with nailing in the UI for my Twitter client. But when I get ready to go live, I'll definitely want to switch to OAuth. It might very well for this reason that Twitter leaves Basic Authentication lying around; it's just easier to develop an app if you don't have to deal with OAuth.

- OAuth (useful beginners guide here) is an authentication protocol that allows users to approve applications to act on their behalf without sharing their password. The basics of it are this; the developer has to inform Twitter directly that they have created an application that will be making calls into their API that require authentication. You fill out the form and register your app at Applications that User Twitter page. Twitter returns to you tokens to be used when requests are being sent back and forth. A Token is generally a random string of letters and numbers that is unique, hard to guess, and paired with a secret key to protect the token from being abused.

The flow then goes something like this: you, the user fire up your Twitter client. If you have not already done so, the Twitter client should direct you to a web page where you can say, "Yes, allow this application to access my information based on my id" (not your username and password). From that point forward, the application sends its key, along with your unique Twitter-system user id, to the API. The Twitter system looks at the key, and the ID, and asks, "has this user authenticated this application". If the answer is yes, the interaction proceeds, if not, it's declined. Remember, this key is coupled with another secret token, so just intercepting the in-transit data won't work (unless the hacker has obtained your secret key somehow).

OAuth is considered sufficiently secure for this sort of interaction, and prevents the problem I described before about being able to capture user credentials, since the user never directly provides credentials to the application. Yes, once you approve the app at the Twitter site, the application can do wonky things, like making bad tweets on your behalf, but as soon as you see that you can either de-authorize the app, or Twitter will ban the application entirely by revoking the tokens. OAuth is most definitely what you should be looking at if you intend to release any kind of Twitter client. It is a VERY common security paradigm, e.g. Facebook uses it, so any developer getting into building apps for social networks should definitely get their head around it.

So, that I said, I want, for now, to be able to make calls as simply as humanly possible into the Twitter API, I don't care if they're secure or not at this point.

To that end, I found the tweetr ActionScript 3 library. By just copying the code in their example "Retrieving One Tweet from authenticated User Timeline", I was able to call into the API with my username and password, and as the name implies, retrieve one tweet from my account (it turned out to be my last one).

I haven't looked at the source code, but, since the library takes a username and password to make the request, and I haven't registered my application, I'm assuming with good reason that this library uses basic authentication, at least for this example. As I said, during this dev phase, that's fine, but I'm going to have to revisit this eventually.

The code looks like this; yes, I took out my username and password. Notice I put this in a Command-based class (it implements the ICommand interface, typically "execute ( )"). So I'm using Commands in the Mate framework. Nice.

private var tweetr:Tweetr;
public function execute ( ) : void
tweetr = new Tweetr();

// set the browserAuth to false so we actually use
// the AIR authentication scheme
tweetr.browserAuth = false;

tweetr.username = "xxx";
tweetr.password = "yyy";

tweetr.addEventListener(TweetEvent.COMPLETE, handleTweetsLoaded);
tweetr.addEventListener(TweetEvent.FAILED, handleTweetsFail);

// tweetr.getUserTimeLine();
tweetr.getFollowers ( );

private function handleTweetsLoaded(event:TweetEvent):void
// assign the latest response to a data object
var tweet : StatusData = event.responseArray [ 0 ] as StatusData;

// trace some data
trace ( tweet.user.profileImageUrl );
trace ( tweet.user.screenName, tweet.text, TweetUtil.returnTweetAge ( tweet.createdAt ) );

private function handleTweetsFail(event:TweetEvent):void
trace ( "TWITTER ERROR ARGH ", );

So far so good; I've found a library that lets me proceed with my development, like creating user interfaces for posting tweets, managing friends and favorites, and so on. I'm using Basic Authentication for now, but I know I need to change it, and since I've done Facebook application development already, I shouldn't have any problem tracking down resources and libraries to get me through this on the Twitter side.

Next, retrieving my own timeline, and creating a view for it, such that I can toggle back 'n forth between the public timeline and my own.

As always, thanks for visiting.

Labels: , , , , , , , , , , ,