coderanger.com blog news about what I am developing and other random thoughts
OAuth Class for Flex
Having just completed a simple class to handle OAuth secure authorisation used by twitter.com and others, I thought I would upload it for others to use.
Its quite simple to use (I have tried to make it as simple and straightforward as possible) and there is an example FlexBuilder project that shows how the class is used with twitter.
Basic usage is split into two parts …
1) the actual request for authorisation:
private var _twitauth:OAuthManager = new OAuthManager();
_twitauth.addEventListener( OAuthEvent.ON_REQUEST_TOKEN_RECEIVED, onRequestTokenReceived );
_twitauth.addEventListener( OAuthEvent.ON_REQUEST_TOKEN_FAILED, onRequestTokenFailed );
_twitauth.addEventListener( OAuthEvent.ON_ACCESS_TOKEN_RECEIVED, onAccessTokenReceived );
_twitauth.addEventListener( OAuthEvent.ON_ACCESS_TOKEN_FAILED, onAccessTokenFailed );
_twitauth.usePinWorkflow = true;
_twitauth.consumerKey = key.text; // Your application key from your twitter.com settings page
_twitauth.consumerSecret = secret.text; // Your application secret from your twitter.com settings page
_twitauth.oauthDomain = "twitter.com";
_twitauth.requestToken();
// callback for "requestToken()" when request token received from twitter
private function onRequestTokenReceived( evt:OAuthEvent ):void
{
// This will redirect to a web page which allows users to accept and receive a pin number
// Normally might be best to display an alert warning user that they will get a web page
// displayed and what they should do with it
_twitauth.requestAuthorisation();
}
// call this method after getting the user to enter the pin number displayed on screen
private function onSendPin():void
{
if( pin.text.length != 7 )
{
Alert.show( "Sorry the PIN number is incorrect, it must be 7 numbers", "Approve Application", Alert.OK );
return;
}
if( !_twitauth.validatePin( pin.text ) )
{
Alert.show( "Sorry the PIN number is invalid and must have been typed incorrectly", "Approve Application", Alert.OK );
return;
}
_twitauth.requestAccessToken( Number( pin.text ) );
}
private function onAccessTokenReceived( evt:OAuthEvent ):void
{
// Store pins and tokens ready for future requests ... might even be good to confirm
// the customerName is what you were expected for this authorisation
accessPin = _twitauth.accessPin;
accessToken = _twitauth.accessToken;
accessTokenSecret = _twitauth.accessTokenSecret;
customerName = _twitauth.currentUserName;
// Now I can do my tweets and whatever
// ........
}
private var accessPin:Number;
private var accessToken:String;
private var accessTokenSecret:String;
private var customerName:String;
2) future requests using saved authorisation tokens:
var twitauth:OAuthManager = new OAuthManager(); twitauth.usePinWorkflow = true; // The following variables are retrieved from where there were stored when first authorised using step 1 twitauth.accessPin = accessPin; twitauth.accessToken = accessToken; twitauth.accessTokenSecret = accessTokenSecret; twitauth.consumerKey = applicationConsumerKey; twitauth.consumerSecret = applicationConsumerSecret; twitauth.oauthDomain = "twitter.com"; // Get our signed data using above keys, ready for sending to twitter var postData:String = twitauth.getSignedURI( "POST", "http://twitter.com/statuses/update.xml", "status=" + encodeURIComponent(tweet.text) ); // Setup our request to twitter using signed information var httpService:HTTPService = new HTTPService; httpService.url = "http://twitter.com/statuses/update.xml"; httpService.useProxy = false; httpService.method = "POST"; httpService.contentType = "application/x-www-form-urlencoded"; httpService.addEventListener( "result", httpPostResult ); httpService.addEventListener( "fault", httpPostFault ); httpService.send( new QueryString( postData ).toPostObject() );
I am currently working on integrating this into my twitter client, twitcher, but there are tricky user interface issues I need to decide upon before it can be completed. Hopefully it won’t be too long and then twitcher will be one of the few (if not the only) twitter desktop app that supports oauth.
Download the OAuth Class or OAuth Twitter Example Class, and please report any bugs or comments to me so they can be looked at.
This entry was posted on Sunday, August 2nd, 2009 at 10:49 pm and is filed under Air and Flex, General.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
August 6th, 2009 at 3:05 pm
A thought – without a web site in the middle – does this mean that the application secret key is sitting on the end-user machine within the application binary … and could be extracted and re-used.
August 6th, 2009 at 6:42 pm
Yes, theoretically that is a possibilty but unlikely, however you can always issue yourself new keys and update your application if you feel its been compromised. Its also good practice to encrypt the tokens and keys that you are storing just as you would encrypt any passwords.
You could also do something like grab the application/consumer key and secret from your application web site (encrypted of course) prior to using them in any requests so they arent stored locally, this means that you can re-issue yourself a new key more easily … not forgetting that if you reissued a new application/consumer key/secret then the user would have to re-authorise the application all over again which is a bit annoying as its not particularly easy in a desktop client.
August 11th, 2009 at 9:26 pm
Thanks for sharing, It seems your example misses as3crypto lib http://code.google.com/p/as3crypto/, and there is a JSON error in OAuthTwitterTest.mxml file.
August 20th, 2009 at 1:01 pm
I am sure I put the external requirements in the readme and source. As for the error, i will check when I get back from vacation. Thanks for the feedback.
August 22nd, 2009 at 8:43 am
I have updated the usage.txt file to include the disclaimers and reference to using the as3crypto library. You are right, I only had the requirements in the OAuthManager class so I have put it in other places including the example as well.
August 31st, 2009 at 2:22 pm
Anyway to go around “Security error accessing url” when using this class on browser application
September 1st, 2009 at 10:09 am
Sorry I havent tested it in a browser situation, I would imagine you might have issues with security contexts. Have you checked out the documentation for the HTTPService class, you may need to use a different class within a browser context … also the PIN based authorisation is not really applicable for non client apps, you may need to change this to use the redirect callback for a better experience for a browser app.
September 6th, 2009 at 2:03 pm
Hi Dan,
Am new to Air development, finding issue in implementing OAuth. Am using flex builder and on run it shows a blank window, none of the UI components are loaded, though the flex builder doesn’t gave any error. Here by attaching the Link of my project file for reference
http://cid-ed9b1a23bacbe8e2.skydrive.live.com/self.aspx/Oauth/oauth.zip
September 6th, 2009 at 7:34 pm
Selvagk:
Your project works fine for me, not sure why the UI components are not loaded without any errors, are you using FlexBuilder 3 or 4?
September 7th, 2009 at 6:00 am
Hi Dan,
It is working right now. I need to include both the” as3crypto” lib and “as3corelib-.92.1″ lib in my project. Thanks for the help
September 7th, 2009 at 7:07 am
Yes that is right, but it would have errored without them I would have thought. Anyway, glad its okay now.
October 13th, 2009 at 2:49 am
Great, working fine now
October 13th, 2009 at 9:32 am
Hi Dan,
Thank you for sharing this class with us!
Sadly I encountered a problem while trying to implement it. I built an Air app using your oauth solution.
It worked fine in the debugger, but when I exported the project and ran it from my desktop, Windows kept asking for the credentials saying that the application was trying to access Twitter through basic authentication.
Do you have any idea where I should look for the bug?
I’ve been using Flash Builder 4 on Vista.
If you want to have a look at how the app behaves: http://www.0142am.com/twica
Many thanks,
Barbara
October 13th, 2009 at 7:19 pm
How does the test application work that is supplied with the OAuth code? Does it exhibit the same behaviour?
October 14th, 2009 at 1:14 pm
Hi,
Thanks for your reply!
I tested the example application and it shows the same behaviour; on certain machines it works fine but on others Windows asks for the credentials. I also tested them on a mac and everything went well. So the problem must be not with the code but with the settings on one’s machine.
Do you have any clues what it might be?
Thank you for your time,
Barbara
October 14th, 2009 at 1:50 pm
I think perhaps you have a proxy server setup and its asking for the proxy server login credentials. Adobe Air does use the Windows Network Settings for communication so perhaps this is different on some of the machines.
November 25th, 2009 at 6:06 am
Hello,
Thank you for providing that great OAuth library,
your great job reduce a lot of work load of me !
Also, I find a problem and when using this library:
1. In getSignedURI, I find that not only POST data needed in oauth_signature, but also need GET parameter,
so I change some code :
————————————————-
OAuthManager.as line 247 :
if(postData.length)
{
var qs:QueryString = new QueryString( postData );
if( qs.length )
{
for( var p:uint = 0; p < qs.length; p++ )
{
newQueryString.add( qs.getParam( p ) );
}
}
}
————————————————-
so, GET data also have calculate a correct oauth_signature.
2. I find that I when tweet some special chars like "(" , "*" , twitter service will return 401 unAuth Error. I wonder that it is the problem of decoding in utf-8?? let the oauth_signature get wrong??
Thank you
Wilfred
November 27th, 2009 at 2:55 am
I have find out the special chars problem since the Encoding in Flex. Flex encodeURIComponent will not encode ‘(‘,’!’ and some special char, so it will get wrong.
I use this encoding method from other developer :
http://blog.dborisenko.com/en/2009/09/05/extended-utf-8-in-oauth-actionscript-library/
December 15th, 2009 at 4:04 pm
[...] that person is Dan Petitt aka Coderanger . I was able to base my OAuth implementation on his great OAuth Class, which really helped me getting started. Thanks [...]
January 11th, 2010 at 4:56 am
asking twitter authentication (username and paswd )when trying to sent a tweet with special charecters( ; ‘ : ).im using the twitter methode as follows
var twitauth:OAuthManager = new OAuthManager();
twitauth.usePinWorkflow = true;
twitauth.accessPin = accessPin;
twitauth.accessToken = accessToken;
twitauth.accessTokenSecret = accessTokenSecret;
twitauth.consumerKey =cnsumerKey ;
twitauth.consumerSecret = cnsumerSecret;
twitauth.oauthDomain = “twitter.com”;
var postData:String = twitauth.getSignedURI( “POST”, “http://twitter.com/statuses/update.xml”, “status=” + tweet_String );
var httpService:HTTPService = new HTTPService;
httpService.url = “http://twitter.com/statuses/update.xml”;
httpService.useProxy = false;
httpService.method = “POST”;
httpService.contentType = “application/x-www-form-urlencoded”;
httpService.addEventListener( “result”, httpPostTweet_Result34 );
httpService.addEventListener( “fault”, httpPostTweet_Fault );
httpService.send( new QueryString( postData ).toPostObject() );
is there any hope…?
thanks.
Arun
January 12th, 2010 at 8:32 pm
I think you should encode your tweet_String variable first:
var postData:String = twitauth.getSignedURI( “POST”, “http://twitter.com/statuses/update.xml”, “status=” + encodeURIComponent(tweet_String) );But as Wilfred Yau says above you may have some issues encoding special characters:
January 15th, 2010 at 10:10 am
Dan,
We have tried with other encoding mechansisms above mentioned.But invalid signature issue is still pertaining if we include charcters like- !,’, etc.Do you have any idea to sort it out.Am also confused with what really is the cause of this error.Is this part of the Base64 encoding class we are using in authorisation.That class has a constant declared as follows
private static const BASE64_CHARS:String = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=”;
These charcters are not part of this constant.Is that may be cause?
Some twitter apis like Tweetre is having no such issue.I wonder how they managed to sort out this issue
Expecting a reply
Ranjith
January 15th, 2010 at 8:17 pm
Where do you get your “BASE64_CHARS” from? and why dont you used the Base64 utils provided in the framework?
January 18th, 2010 at 6:10 am
Dan,
Static variable BASE64_CHARS is declared in the class Base64 in com.hurlant.util package itself.
Arunraj