OAuth 2.0 Library for ActionScript

Here at Adobe, we’ve been working really hard recently on our latest big project: Adobe Creative Cloud. For anyone that is unfamiliar or wasn’t able to attend our latest MAX conference, here is how we describe the project, straight from our press release

“Adobe Creative Cloud reinvents creative expression by enabling a new generation of services for
creativity and publishing, that embrace touch interaction to re-imagine how individuals interact with
creative tools and build deeper social connections between creatives around the world.”

-Kevin Lynch, CTO, Adobe Systems

In a nutshell, Creative Cloud is really an ecosystem that includes a multitude of applications for various devices that facilitate creative workflows, all backed by a cloud storage solution. Now that I’m done with the marketing, I can get to the good stuff :)

One of the major tasks that we’ve decided to undertake while doing this project was to switch from our current authentication system to a standards-based OAuth 2.0 authentication and authorization system. This was (is) a large undertaking and included building the likes of an OAuth 2.0 server, building and supporting new OAuth 2.0 compatible clients, as well as converting all existing systems to the new one. As part of this project, I ended up creating some OAuth 2.0 libraries that our touch-tooling applications use to interact with our system. While doing this, I realized that a lot of this work can easily be open-sourced and used with any OAuth 2.0 compliant service! And so, here we are!

 
Out in the Open
What I’ve created is exactly how it sounds: an OAuth 2.0 library for ActionScript. It abides by the OAuth 2.0 specification (version 2.15) and so is compatible with any OAuth 2.0 service! That includes services like Facebook Platform, Google APIs, Foursquare APIs, and many many more.

 
What it Does
If you are unfamiliar with the OAuth 2.0 workflow, it is really quite simple…

  1. Your application makes a request to the server to get an access token.
    • An access token is what is used to access a protected resource, say, an API to post a status update.
  2. The user authenticates and authorizes the use of said protected resource by the application on behalf of the user.
    • For example, the user logs in and allows your application to post a status update on their behalf.
  3. An access token is granted and returned back to your application.
    • The access token will be restricted for use with only the specific permissions that were authorized in Step 2.
  4. You use the access token for whatever you want!
    • Using the same example, your application then uses this token to make a call to update your status.

The library is only in charge of steps 1-3. It will just get you your access token. What you do with it, and what API calls you make with it, are up to you.

 
How to Use It
This library is designed for use in mobile devices using AIR. Because of that, it makes use of the StageWebView object to display the user consent page (the form that the user must log into and authorize your application in Step 2). I’ve created a very simple mobile demo application that does exactly this. Here is the important part of the code…

// set up our StageWebView object to use our visible stage
stageWebView.stage = stage;
 
// set up the call
var oauth2:OAuth2 = new OAuth2("https://accounts.google.com/o/oauth2/auth", "https://accounts.google.com/o/oauth2/token", LogSetupLevel.ALL);
var grant:IGrantType = new AuthorizationCodeGrant(stageWebView, "INSERT_CLIENT_ID_HERE", "INSERT_CLIENT_SECRET_HERE", "http://www.mysite.com", "https://www.googleapis.com/auth/userinfo.profile");
 
// make the call
oauth2.addEventListener(GetAccessTokenEvent.TYPE, onGetAccessToken);
oauth2.getAccessToken(grant);
 
function onGetAccessToken(getAccessTokenEvent:GetAccessTokenEvent):void
{
	if (getAccessTokenEvent.errorCode == null && getAccessTokenEvent.errorMessage == null)
	{
		// success!
		trace("Your access token value is: " + getAccessTokenEvent.accessToken);
	}
	else
	{
		// fail :(
	}
}  // onGetAccessToken

You’ll see that the code is quite simple. First, we set up the StageWebView object. Then, we prepare the OAuth2 object by invoking its constructor with the appropriate values. In the third step, we attach an event-listener and make the call. Finally, in the event handler function, we handle the response. That’s it!

 
Demo
I’ve created a sample demo application that demonstrates the usage of this library. Using the same sample code as above (with the appropriate values filled in), connecting to Google’s OAuth 2.0 APIs, the sample app looks like this…

Take it for a spin and let me know what you think!

ActionScript OAuth 2.0 Mobile Demo Application

 
Code, please!
I’ve released the code under the Apache License, Version 2.0 and made it all available on GitHub! Please, fork and extend!

ActionScript OAuth 2.0 Library

That’s it! Hopefully some of you will find this project useful. And as always, I love hearing from you so let me know what you think! Happy coding =)

 
Update: As requested, I’ve removed the dependencies on the Flex framework so this library is now a pure AS3 library. Enjoy!

 
Charles

58 Responses to OAuth 2.0 Library for ActionScript

  1. Pingback: OAuth 2.0 Library for ActionScript

  2. George says:

    Nice work. OAuth is now very important these several years especially for mobile data sharing projects.

    • Vanessa says:

      When you intialize the FB SDK with stauts:true it will fetch the login stauts from the user and store it. From that point on when you make calls to FB.getLoginStatus() it isnt accessing fetching the latest data from FB but is instead referring to the locally stored variables that were set at the point of FB.init() I think its only refreshed once every 20 mins (ver ) however you can force the refresh by doing this:FB.getLoginStatus(function() {…}, /*FORCE*/ true);This should then fire your auth.login event or you could just pass the handler you defined for that event to FB.getLoginStatus tambe9m.Can even go a set further and poll this function like:setTimeout(function() { FB.getLoginStatus(function() {…}, /*FORCE*/ true);}, 10000); // poll every 10 seconds

  3. Shawn says:

    Thanks for releasing this! But is there anyway we can get rid of all the Flex SDK dependancies??

    • Charles Bihis says:

      Hi Shawn. I hadn’t thought about making it pure AS3 when I was initially making the library, but I should have. That’s a great suggestion. It looks like I only need to replace the HTTPService calls with URLLoader calls, and remove/replace the logging. That’s not so bad. If I have some free time, I’ll try and fit in those changes :)

  4. Shawn says:

    For anyone else doing pure AS3 project’s, you’ll need to include these guys from a 3.x SDK:
    framework.swc
    rpc.swc
    framework_rb.swc

  5. Pingback: OAuth 2.0 Library for ActionScript « eaflash

  6. katopz says:

    Thanks! it’s working!

    btw do you plan for pure as3 project support? from my test swf size increase to 1.4MB just for this…so it would be nice if i can do this without flex stuff ;)

    • Charles Bihis says:

      Yes, that’s a great suggestion. I hadn’t thought about it until now, but I think I’ll try and make those changes when some time frees up for me. Thanks for trying it out!

  7. Shawn says:

    I may try submitting this myself as a pull request, but it would be great if you would also add a buildRequest API?

    It’s great to authenticate, but when we need to make subsequent OAuth calls, are stuck adding the headers by hand.

    Thanks!

    • Charles Bihis says:

      That’s another great suggestion! Again, if some time frees up for me, I’ll be sure to add it!

  8. Elliot Geno says:

    It’s a neat API for AIR!

    Do you think StageWebView would ever come to the Flash Player? I realize including a webkit renderer in the player would balloon Flash player’s file size. But it would reduce some of the inconsistencies between the two and make a ton of new capabilities available to games and applications!

    • Charles Bihis says:

      Hi Elliot. My hunch is no. You’re right, it would add a lot of interesting capabilities to Flash games and applications, but I’m guessing it would stay out for the exact reason you mentioned: it would balloon the size of the Flash Player runtime too much considering what you get and the target audience and use for the Flash runtime. I don’t work on the Flash team, though, so you never know!

  9. Does this work w/ Air Mobile on Mobile? Like IOS and Android?

  10. Wow, this is awesome stuff! Thanks alot Charles!

    I’ll agree with the other commenters that a pure AS3 version would be great. Thanks for contributing this to the Flash / AIR community.

    - Bruce

  11. Pingback: Adobe 发布 ActionScript OAuth 2.0 库 | 蛋丁-互联网的一道菜

  12. Chuck Horton says:

    Thanks for the library and the demo it is very useful. Can you give example of refreshing the access token? FYI the ASDocs link at Github is broken (http://charlesbihis.github.com/actionscript-oauth2/docs/).

    • Charles Bihis says:

      Hi Chuck. Usage for the refreshToken() method is actually quite similar to the getAccessToken() method. Instead of passing in an IGrant object, you simply pass in the 3 necessary parameters directly instead. And instead of listening for a GetAccessTokenEvent event, you listen for a RefreshAccessTokenEvent event. That’s about it!

      Oh, and thanks for pointing out the broken docs. I’ve just fixed them :)

      • Chuck Horton says:

        Hi Charles, now that I am getting the Refresh Token when authorizing the refreshToken() routine works fine. Below is my code to refresh the access token.

        protected function getRefreshToken():String {
        trace(“getRefreshToken”);
        var resultValue:String = “”;

        // set up the call
        var oauth2:OAuth2 = new OAuth2(OAUTH_AUTH_URL, OAUTH_TOKEN_URL, LogSetupLevel.DEBUG);
        oauth2.addEventListener(RefreshAccessTokenEvent.TYPE, onRefreshAccessToken);
        oauth2.refreshAccessToken(googleRefreshToken,CLIENT_ID,CLIENT_SECRET,CLIENT_SCOPE)

        function onRefreshAccessToken(refreshAccessTokenEvent:RefreshAccessTokenEvent):void {
        if (refreshAccessTokenEvent.errorCode == null && refreshAccessTokenEvent.errorMessage == null) {
        trace(“onRefreshAccessToken SUCCESS”);
        accessToken.text = refreshAccessTokenEvent.accessToken;
        tokenType.text = refreshAccessTokenEvent.tokenType;
        expiresIn.text = refreshAccessTokenEvent.expiresIn + “”;

        googleAccessToken = refreshAccessTokenEvent.accessToken;
        resultValue = googleAccessToken;
        googleTokenExpires = new Date( new Date().time + (refreshAccessTokenEvent.expiresIn*1000) );
        expiresAt.text = DateFormatEEEMMMDDYYYYTIME.format(googleTokenExpires);

        // Save new accessToken and when it expires
        accessTokenObject = new Object();
        accessTokenObject.accessToken = googleAccessToken;
        accessTokenObject.refresh = googleRefreshToken;
        accessTokenObject.expires = googleTokenExpires;

        // Creating ByteArray to store access token
        var accessTokenBytes:ByteArray = new ByteArray;
        // Writing access token object into a ByteArray
        accessTokenBytes.writeObject(accessTokenObject);
        // Storing access token bytes in EncryptedLocalStore
        EncryptedLocalStore.setItem(GOOGLE_ACCESS_TOKEN_STORE, accessTokenBytes);

        } else {
        trace(“ERROR errorCode: ” + refreshAccessTokenEvent.errorCode + ” — errorMessage: ” + refreshAccessTokenEvent.errorMessage);
        // show the contents of the response in the results page
        currentState = “results”;
        accessToken.text = “ERROR errorCode: ” + refreshAccessTokenEvent.errorCode + ” — errorMessage: ” + refreshAccessTokenEvent.errorMessage;
        googleAccessToken = “ERROR”;
        }
        }
        return googleAccessToken;
        }, Chuck

        protected function getRefreshToken():String {
        trace(“getRefreshToken Need accessTokenBytes”);
        var resultValue:String = “”;

        // set up the call
        var oauth2:OAuth2 = new OAuth2(OAUTH_AUTH_URL, OAUTH_TOKEN_URL, LogSetupLevel.DEBUG);
        oauth2.addEventListener(RefreshAccessTokenEvent.TYPE, onRefreshAccessToken);
        oauth2.refreshAccessToken(googleRefreshToken,CLIENT_ID,CLIENT_SECRET,CLIENT_SCOPE)

        function onRefreshAccessToken(refreshAccessTokenEvent:RefreshAccessTokenEvent):void {
        if (refreshAccessTokenEvent.errorCode == null && refreshAccessTokenEvent.errorMessage == null) {
        trace(“onRefreshAccessToken SUCCESS”);
        accessToken.text = refreshAccessTokenEvent.accessToken;
        tokenType.text = refreshAccessTokenEvent.tokenType;
        expiresIn.text = refreshAccessTokenEvent.expiresIn + “”;

        googleAccessToken = refreshAccessTokenEvent.accessToken;
        resultValue = googleAccessToken;
        googleTokenExpires = new Date( new Date().time + (refreshAccessTokenEvent.expiresIn*1000) );
        expiresAt.text = DateFormatEEEMMMDDYYYYTIME.format(googleTokenExpires);

        // Save new accessToken and when it expires
        accessTokenObject = new Object();
        accessTokenObject.accessToken = googleAccessToken;
        accessTokenObject.refresh = googleRefreshToken;
        accessTokenObject.expires = googleTokenExpires;

        // Creating ByteArray to store access token
        var accessTokenBytes:ByteArray = new ByteArray;
        // Writing access token object into a ByteArray
        accessTokenBytes.writeObject(accessTokenObject);
        // Storing access token bytes in EncryptedLocalStore
        EncryptedLocalStore.setItem(GOOGLE_ACCESS_TOKEN_STORE, accessTokenBytes);

        } else {
        trace(“ERROR errorCode: ” + refreshAccessTokenEvent.errorCode + ” — errorMessage: ” + refreshAccessTokenEvent.errorMessage);
        // show the contents of the response in the results page
        currentState = “results”;
        accessToken.text = “ERROR errorCode: ” + refreshAccessTokenEvent.errorCode + ” — errorMessage: ” + refreshAccessTokenEvent.errorMessage;
        googleAccessToken = “ERROR”;
        }
        }
        return googleAccessToken;
        }

  13. Chuck Horton says:

    In your example, and in your screenshot above no Refresh Token is shown/returned. Why is this?

    • Charles Bihis says:

      Hi Chuck. According to the OAuth 2.0 spec, the refresh token is an optional value to be returned.

      http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-5.1

      As you can see, the only required return values are the access token and token type. Depending on the service you are using, and their intended usage, they may or may not return a refresh token. This appears to be the case with my demo as well as in the screenshot.

      • Chuck Horton says:

        Thanks for the replies and explanations Charles. I am trying to get a refresh token using AuthorizationCodeGrant with the following scope “https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/userinfo.email https://www.google.com/m8/feeds“. No refresh token is returning. So I went to Google’s OAuth 2.0 Playground at https://code.google.com/oauthplayground and tested this scope. Which does return a refresh token in step two. I also tested the scope in the demo of “https://www.googleapis.com/auth/userinfo.profile and it also returned a refresh token. Is the AuthorizationCodeGrant in your library the correct way to get a refresh token?

        • Chuck Horton says:

          I found the problem. For Google you have to included the parameter access_type=offline to get a refresh token. To get a fresh token I changed line 101 in AuthorizationCodeGrant.as to:

          var url:String = authEndpoint + “?response_type=code&client_id=” + clientId + “&redirect_uri=” + redirectUri + “&access_type=offline”;

          • Charles Bihis says:

            Hi Chuck. I’ve just committed a change that allows you to pass in arbitrary query parameters to be added to the authentication URL. This can be used specifically for this purpose. Hope that helps!

            Charles

  14. Alejandro R. says:

    Thanks for sharing. I am trying to use this and was wondering if you have an example of its use with the Flickr API.

    I tried it and am getting an error about a missing parameter “missing oauth_token parameter”.

    The Flickr API documentation is a bit cryptic so I am still trying to figure out what may be the missing parameter.

    • Bob says:

      I’m trying to get oauth working for flickr too, if you made any progress / have an example would appreciate seeing it. I spent quite some time trying to get the iotashan library to work on flickr and kept having problems in the final step. Hopefully this one works? If I have success I’ll come back and post it.

      • Charles Bihis says:

        Hi all,

        Just from some quick reading online, it looks like Flickr uses the OAuth 1.0 protocol. This library is designed for use with the OAuth 2.0 protocol. And, unfortunately, although they are similar, the 1.0 and 2.0 versions of the protocol do NOT interchange. I haven’t tested this myself, but I suspect this is the reason why you are having trouble using this library to interface with Flickr. Hopefully they adopt OAuth 2.0 soon :)

        Charles

  15. Lucas says:

    Thanks for sharing!
    it will be a usefull tool

  16. Eric Wilde says:

    Charles,

    Thanks for the code. This is very helpful. I do have a problem, though. I suspect a setup problem on my system but am unsure where to turn next.

    I’m doing just an authentication and not an authorization:

    var oauth2:OAuth2 = new OAuth2(“https://accounts.google.com/o/oauth2/auth”, “https://accounts.google.com/o/oauth2/token”, LogSetupLevel.DEBUG);
    var grant:IGrantType = new ImplicitGrant(stageWebView, “INSERT_CLIENT_ID_HERE”, “http://www.mysite.com”, “https://www.googleapis.com/auth/userinfo.profile”);

    I’ve replaced the client ID appropriately and the redirect url is “http://localhost”.

    The StageWebView is throwing a “load error”. I’ve traced that down to the URLLoader ithrowing an IOError for http://localhost. It seems like the redirect never comes in. Here’s the debug log:

    2012/7/19 10:57:1.142 [INFO] com.adobe.protocols.oauth2.OAuth2 Initiating getAccessToken() with implicit grant type workflow
    2012/7/19 10:57:1.145 [INFO] com.adobe.protocols.oauth2.OAuth2 Loading auth URL: https://accounts.google.com/o/oauth2/auth?response_type=token&client_id=xxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost&scope=https://www.googleapis.com/auth/userinfo.profile
    2012/7/19 10:57:1.146 [INFO] com.adobe.protocols.oauth2.OAuth2 onLocationChange Loading URL: https://accounts.google.com/o/oauth2/auth?response_type=token&client_id=xxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost&scope=https://www.googleapis.com/auth/userinfo.profile
    2012/7/19 10:57:2.944 [INFO] com.adobe.protocols.oauth2.OAuth2 onLocationChange Loading URL: https://accounts.google.com/ServiceLogin?service=lso&passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/userinfo.profile%26response_type%3Dtoken%26redirect_uri%3Dhttp://localhost%26client_id%xxxxxxxxxxxxxx.apps.googleusercontent.com%26hl%3Den-US%26from_login%3D1%26as%3D1b97036b66d25b2f&ltmpl=embedded&shdf=CocBCxIGZG9tYWluGg5oeWRyYXByb3RvdHlwZQwLEhV0aGlyZFBhcnR5RGlzcGxheU5hbWUaDmh5ZHJhcHJvdG90eXBlDAsSFXRoaXJkUGFydHlEaXNwbGF5VHlwZRoSTkFUSVZFX0FQUExJQ0FUSU9ODAsSEXRoaXJkUGFydHlMb2dvVXJsGgAMEgNsc28iFJVwmSWk1Aw4p7gFWIP_6_BaOZanKAEyFDzBpyQm6lKhzIJ4MvMQcYTfp1f4&scc=1
    2012/7/19 10:57:3.760 [INFO] com.adobe.protocols.oauth2.OAuth2 onLocationChange Loading URL: https://accounts.google.com/ServiceLogin?service=lso&passive=1209600&continue=https://accounts.google.com/o/oauth2/auth?scope%3Dhttps://www.googleapis.com/auth/userinfo.profile%26response_type%3Dtoken%26redirect_uri%3Dhttp://localhost%26client_id%xxxxxxxxxxxxxx.apps.googleusercontent.com%26hl%3Den-US%26from_login%3D1%26as%3D1b97036b66d25b2f&ltmpl=embedded&shdf=CocBCxIGZG9tYWluGg5oeWRyYXByb3RvdHlwZQwLEhV0aGlyZFBhcnR5RGlzcGxheU5hbWUaDmh5ZHJhcHJvdG90eXBlDAsSFXRoaXJkUGFydHlEaXNwbGF5VHlwZRoSTkFUSVZFX0FQUExJQ0FUSU9ODAsSEXRoaXJkUGFydHlMb2dvVXJsGgAMEgNsc28iFJVwmSWk1Aw4p7gFWIP_6_BaOZanKAEyFDzBpyQm6lKhzIJ4MvMQcYTfp1f4&scc=1
    2012/7/19 10:59:13.141 [INFO] com.adobe.protocols.oauth2.OAuth2 onLocationChange Loading URL: https://accounts.google.com/ServiceLoginAuth

    Its after the redirect to https://accounts.google.com/ServiceLoginAuth that the IOError is thrown.

    Any ideas or help are much appreciated.

    –Eric

    • Charles Bihis says:

      Hi Eric,

      It’s hard to say what the error is. When I tried to replicate, I got an error of “The redirect URI in the request: http://localhost did not match a registered redirect URI”, but my log output was very similar to yours. Maybe make sure that your redirect URI is registered with your application with Google correctly. That may be the culprit. Hope that helps.

      Charles

      • Charles Bihis says:

        Hi Eric,

        Actually, doing a bit of digging, I found that that particular redirect URL (i.e. localhost) is a special one recognized by Google’s APIs. When it sees this, it returns the response in a different format than if it were another URL. See here for more details…

        https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi

        Sounds like you’ll actually need something listening at localhost to pick up the response. Otherwise, try changing that to, say, “http://www.adobe.com”. That should use the library as it was intended and you should see the access token in the response in the app. Don’t forget to update the redirect URL in the API console though! Hope that helps.

        Charles

  17. Dom says:

    Does this still work for folks? When using the sample code, my stageWebView gets stuck with “Please copy this code, switch to your application and paste it there:”.

    • Charles Bihis says:

      Hi Dom, that sounds like your request or your application is set up a little differently. Appears as though you do actually get an access token, but it is displayed in the StageWebView instead of returned as a response. What does your grant object look like?

      • Dom says:

        Hi Charles, thanks for responding. My grant object is a copy/paste (as far as I can tell) of the sample.

        var grant:IGrantType = new AuthorizationCodeGrant(stageWebView, “myIdIsHere”, “mySecretIsHere”, “urn:ietf:wg:oauth:2.0:oob”, “https://www.googleapis.com/auth/userinfo.profile”);

        I have tried running this as both an AIR desktop app and a mobile app and both give same result.

        • Charles Bihis says:

          Hi Dom,

          I see what’s going on. That redirect URI is a special redirect recognized by Google’s APIs. When it sees this, it returns the response in a different format than if it were another URL. See here for more details…

          https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi

          Using that redirect URI, Google will actually return the authorization code within the title bar of the browser. That is not what the library is expecting, and so you’ll either have to change your configuration (i.e. that redirect URI), or modify the library accordingly. Anyways, as I mentioned to Eric, above, I would just try changing the redirect URI to something like “http://www.adobe.com”. That should bypass these special URIs that Google is looking for and so the library and sample app should work as expected. Hope that helps.

          Charles

  18. Sebastian says:

    Hi, im having an issue. Currently the code for authorization works local for a Air Android App, the code returns the token, and Im able to request to the google reader API some feeds, but at the time I tested on the device, it started to return a http 401 error, it says that i have to send the headers, specífically the Authorization header with the token to the API url. I dont know what Im exactly doing wrong, but a little example on how to call any api sending the headers (or not, i dont know if they are necessary) will be very helpfull,

    thanks

  19. Abid Amin Khan says:

    Hi! I am using your Classes in FlashCS6 for my Project. I constantly get this error.

    1046: Type was not found or was not a compile-time constant: StageWebView.

    and the error is from ImplicitGrant.as file.

    So, can i use it for FlashCS6 instead of AIR?

    Thanks

    • Charles Bihis says:

      Hi Abid. This project necessarily makes use of the StageWebView class to display the user-consent form. The StageWebView class is part of the AIR SDK and, because of this, the AIR dependency is required.

  20. Aleksandr R. says:

    Hi!
    >> This library is built for use with >Flash/Flex/AIR< projects to facilitate communication with OAuth 2.0 services.

    But the library has AIR dependencies: StageWebView, LocationChangeEvent.
    Is it possible to use this library for a simple (non-AIR) web-projects (for example flex-sdk-4.0.1, 10 FP)?
    Maybe someone has a link to another AS3 library for oauth2 (facebook, twitter, google etc.)?

    Thanks.

  21. John M. says:

    Hi. Firstly thanks for this library… saved me a bundle of time and headaches.

    I did have several issues with the process though, as the redirects are no longer working. In your code you are using the URL’s on the redirects to determine success, and Google no longer allows you to add “spoof” URLs to bypass their API, so instead you need to use the page title on the authorization redirect page. To get this you need to use the Event.COMPLETE event and not the LocationChangeEvent.LOCATION_CHANGE for the stageWebView. Your extraction of the code also needs to be modified to reflect this.

    Once I changed this, things worked great!

    Thanks

    • Charles Bihis says:

      Hi John. Thanks for pointing that out! I’ve made the necessary changes in the library and checked them in.

  22. Christian Lins says:

    Hi, Charles!!! Thanks for this library…

    I’d like to know if it’s possible to use this library with a non-AIR project (flex web-project for example)…

    • Charles Bihis says:

      Hi Christian. The library makes use of the StageWebView class which is part of the AIR SDK, so unfortunately no, you won’t be able to use this library for web-only applications.

  23. Has any one been able to get this to work with Salesforce? I looks like it gets past extracting the auth code but in
    getAccessTokenWithAuthCode the following load fails. In the reply I get an invalid grant error with an invalid authorization code message. I know the code is good. My suspicion is that there is a header value missing. An older actionscript library that I have used has the following that works:
    headers["code"] = requestToken;
    headers["grant_type"] = “authorization_code”;
    headers["client_id"] = publicKey;
    headers["client_secret"] = privateKey;
    headers["redirect_uri"] = redirectURI;
    headers["Accept"] = “application/jsonrequest”;
    headers["Cache-Control"] = “no-cache, no-store, must-revalidate”;
    I wonder if we need this header: headers["Accept"] = “application/jsonrequest”;

  24. Lue Try says:

    On 16 May 2006, Flickr updated its services from beta to “gamma”, along with a design and structural overhaul. According to the site’s FAQ, the term “gamma”, rarely used in software development, is intended to be tongue-in-cheek to indicate that the service is always being tested by its users, and is in a state of perpetual improvement.^,

    Newly released piece of writing produced by our personal web site
    <http://caramoan.co/

  25. Tom says:

    Did anyone get it to work for the Twitter api?
    I can’t get it to work and could need some help! :)

  26. Pingback: oAuth 2.0 Library - Flashforum

  27. lahmid says:

    i’d use it in my project mobile but i need this librairy in javascript langage is it possible ?? please some help, i want create an app sencha-phoneGap that send informations to a google table fusion that need an Oauth2 to write into it !!

  28. lahmid lhocine says:

    i want use it in my project mobile but i need this librairy in javascript langage is it possible ?? please some help, i want create an app sencha-phoneGap that send informations to a google table fusion that need an Oauth2 to write into it !!

  29. segi says:

    I need to consume these services in Flash for desktop AIR. I am working Flash CS6.
    I am trying this with source code and not the swc. So I did following steps:
    I added the dependencies like ‘as3commons-logging-2.7.swc’ into my file.
    I imported the required classes in my main class.

    import com.adobe.protocols.oauth2.*;
    import com.adobe.protocols.oauth2.event.*;
    import com.adobe.protocols.oauth2.grant.*;

    When I am trying to compile, it shows me some errors. on investigating, I found that in OAuth2 class ‘JSONParseError’ has been imported and used.
    import com.adobe.serialization.json.JSONParseError;
    But in the source I downloaded, I could not found any such file.
    Please advice.

  30. Kim says:

    The lib doesn’t seem to work with Twiiter… is this normal ? Anyone made this work ?

    • Charles Bihis says:

      Hi Kim. Twitter doesn’t actually fully support version 2 of the OAuth protocol. They fully support OAuth 1 right now, with only limited support for OAuth 2. So unfortunately, until Twitter adds full OAuth 2 support, this library won’t work with their APIs.