Email Updates RSS Subscribe
Line

This blog is created and maintained by the technical team at Hook in an effort to preserve and share the insights and experience gained during the research and testing phases of our development process. Often, much of this information is lost or hidden once a project is completed. These articles aim to revisit, expand and/or review the concepts that seem worth exploring further. The site also serves as a platform for releasing tools developed internally to help streamline ad development.

Launch
Line

Hook is a digital production company that develops interactive content for industry leading agencies and their brands. For more information visit www.byhook.com.

Line

Facebook Canvas App OAuth Authentication

Line
Posted on November 8th, 2010 by Jake
Line

So here we are 6 months past our original post about using flash within a Facebook IFrame/Canvas application. Much has changed in Facebook land since then. The two items most related to our posts are the crossdomain.xml file change and the Canvas page authentication change. So, what does this mean? Well its good and bad news.

The good news is you no longer need to host your .swfs on https. Which is cool, because you can skip the whole first half of the “Suffering” section in the last post. You no longer need to buy a cert and get it configured and set up on your web server. Sanity restored…

The bad news is that our old authentication system no longer works with canvas pages. Truthfully this is fine, and OAuth is a better, more standard method anyway. However, this means we needed to up update our index page to make this all continue to work. Conveniently that is what this post is all about. I suggest having a read through the “Pain” and “Joy” sections of the last post to get familiar with our library and the general facebook app setup. Below is essentially the list of things that you need to change in order to make the example from the last post work (you can download the new example here)

The first change is in the Developer Application on Facebook. There is a setting that you need to change for your app to allow the new authentication method to work:
Facebook Canvas Settings

In the advanced tab you need to enable the OAuth 2.0 for Canvas(beta) feature, and then simply click Save at the bottom of the page. And thats about it for the Facebook app side of things.

All we have to do now is update the index page to take advantage of the Facebook PHP sdk’s ability to grab the necessary info, such as the User ID and the Access Token.

As you’ve no doubt guessed the new index page is a php page. However it doesn’t look THAT much different from the old index page. At the top there are still a set of constants that you need to change in order for this to work with your app. You will need to change:

FACEBOOK_APP_ID
this is the ID of your app from the Developer page for your app

FACEBOOK_SECRET
this is the “Application Secret” from the Developer page for your app

SCOPE
this is the same as before, just a comma separated list of the permissions your app needs
http://developers.facebook.com/docs/authentication/permissions

MAIN_SWF
this is a full url to the swf you want to load in to the loader (your main app swf)

MAIN_SWF_WIDTH
this is the width of your swf

MAIN_SWF_HEIGHT
this is the height of your swf

LOADER_SWF_VER
this is the lowest version of the flash player that is required to run your app

$redirect_url
this is the url to the canvas page on facebook.
(eg. “http://apps.facebook.com/hookfbloaderexample/”)

If you fill out all of those things, and replace your old index.html file with this php one, you are pretty much done. Everything should work again. Yey for working!

Ok, so whats going on here exactly?

$config = array
(
   'appId'  => FACEBOOK_APP_ID,
    'secret' => FACEBOOK_SECRET,
    'cookie' => true
);

First up is the $config list. This is essentially a value object that is passed in during the creation of the Facebook object. The Facebook object constructor stores those values for later use during its lifetime.

The explanation for each of these configuration options can be found in the comments about the constructor in the facebook.php file:

/**
  * Initialize a Facebook Application.
  *
  * The configuration:
  * - appId: the application ID
  * - secret: the application secret
  * - cookie: (optional) boolean true to enable cookie support
  * - domain: (optional) domain for the cookie
  * - fileUpload: (optional) boolean indicating if file uploads are enabled
  *
  * @param Array $config the application configuration
  */

So far pretty straight forward.

Using that $config list we then create the Facebook object and store it in $facebook:

$facebook = new Facebook($config);
$session = $facebook->getSession();

Once we have the new Facebook object, we make an attempt to get the current session info. The Facebook object first looks to see if there is a signed request already stored in the object from a previous encounter. If so, it creates a new session from the signed request, and returns that. If that doesn’t exist, it check the $_REQUEST global for the “session” parameter. If that is there, it validates the session info, and returns that. Lastly, if neither of those methods work, and you have “cookie” set to true in the config list, then it will check for a previously saved cookie. If that exists, and has the session info, it validates that, and returns it. Otherwise it was not able to create a good session, and returns null.

The next step is to see if the returned session is null. If not, then we grab the access token from the returned $session, and make an api call signed with that token.

try
{//try
         $params = array('access_token' => $session['access_token']);
       $userID = $facebook_client->getUser();
       $me  = $facebook_client->api('/me', $params);       
}//try

If that fails, then our session is out of date, or has otherwise been invalidated. If this is the case we start the user authentication process. If our session is good, we store the access token from the session, so we can pass that into our swf later on.

However if the returned $session from before IS null, we start the user authentication process in the doAuth() method.

function doAuth($url)
{//doAuth
   $newLoc = "<script type=\"text/javascript\">\ntop.location.href = \"$url\";\n</script>";
    echo $newLoc;
   exit();
}//doAuth

This simply does a redirect to the facebook authentication page, much like we did in the other setup. Once the user is authenticated, they are redirected back to this index.php page and now there is a valid session from which we can grab the access token.

The other thing that has changed is what data we pass into the swf. This has been trimmed down to just the user id and the access token like so:

<script type="text/javascript">
           var flashvars = {};
           flashvars.access_token = "<?php echo($accessToken)?>";
           flashvars.fb_sig_user = "<?php echo($userID)?>";
           flashvars.mainSWF = "<?php echo(MAIN_SWF)?>";
           var params = {};
           params.scale = "noscale";
           params.allowScriptAccess = "always";
           var attributes = {};
           attributes.id = "flashContent";
           swfobject.embedSWF("swf/FBGameLoader.swf", "myAlternativeContent", "<?php echo(MAIN_SWF_WIDTH)?>", "<?php echo(MAIN_SWF_HEIGHT)?>", "<?php echo(LOADER_SWF_VER)?>", "swf/expressInstall.swf", flashvars, params, attributes);
</script>

As you can see, the access token and the user id are passed in through the flash vars. From this point on everything else works exactly the same as it did before. Our facebook manager class hasn’t changed and everything should just continue to work. Please see our other IFrame/Canvas facebook app post. This has a fairly thorough explanation of the Flash side of things.

As before our live example can be found here.
http://apps.facebook.com/hookfbloaderexample

And the new files for download can be found here:
http://labs.byhook.com/facebookoauth/FacebookCanvasOAuthExample.zip

Official Facebook Example:
https://github.com/facebook/php-sdk/blob/master/examples/example.php

SDK Download:
https://github.com/facebook/php-sdk

*** QUICK TIP ***
Over the weekend I ran into a situation where using this loader wasn’t super convenient. The issue is when dispatching the “FacebookEvent.GET_FACEBOOK” the loader tries to call the method (stored in the event) on the document class of the swf that was just loaded in (your main app swf). Which means that you have to put the receiving method at the document class level. Depending on the structure of your app, this may not be convenient.

There is a simple way around this. Just don’t use the loader :) All that is really needed in your main app swf is this line:

_fb = new FacebookManager(loaderInfo);

The loader basically creates this FacebookManager object and passes it into the document class. The one thing that you need to note, is that you need access to your SWF’s loaderInfo object. Which means you probably need access to the stage before you create this FacebookManager object.

Line
29 Responses to “Facebook Canvas App OAuth Authentication”
  1. Hi,
    I am building a canvas app using Java as my server side framework. When I try to do a redirect of the top window to the oauth URL, I get a “Permission Denied” error in internet explorer.

    I can see that your app is executing the same Javascript as mine and it works fine for me in IE.

    Is there something I’m not seeing that you did to get around this IE permissions issue?

    Thanks,
    Barry

  2. Ellipsis says:

    Jake,

    Thank you for all your responses so far. One last question, How to determine whether the user is accessing the facebook app or the actual website?

    Eg. in your case, how do check if user is at http://apps.facebook.com/hookfbloaderexample or hookfbloaderexample.com ?

    Cheers,

  3. Ellipsis says:

    Jake,

    Thank you for all your responses so far. One last question, How to determine whether the user is accessing the facebook app or the actual website?

    Eg. in your case, how do check if user is at http://apps.facebook.com/hookfbloaderexample or hookfbloaderexample.com ?

  4. sindr0me says:

    Is it safe to pass access token in flashvars?

    • Jake says:

      I’m not sure what you mean exactly, but when the page loads, the access token is passed to the page. So passing that to flash doesn’t make it any less safe. The real danger is someone catching that access token while its in transit. Which is why Facebook has finally started to allow users to connect with https.

  5. Ellipsis says:

    Hello Jake,

    Thank you for this wonderful tutorial and taking time to respond to fellow developer questions.

    I like your way of facebook canvas authentication. It’s pretty simple and works well. If I understand this right, this only helps to get the access token. It doesn’t help to make sure that user is logged in (I know it kind of does). Here is my problem: I am looking for something that I can include in all of my php files to make sure that user is valid and session is still going on. Something like fbmain.php shown in the tutorial at below mentioned link. But If I use your example, it’s just for one time use, since anytime it is use it’s going to redirect the user to “redirect_url”. Is there any way to use one of them? Either your way or fbmain.php. I think it will be redundant to use both, ie your way to oauth and than include fbmain.php so make sure that session is going on.
    Link: http://thinkdiff.net/facebook/php-sdk-graph-api-base-facebook-connect-tutorial/

    May be I am not looking at this whole thing in a right way. Any guidance will be much appreciated.

    Cheers

    • Jake says:

      Hey Ellipsis, you can use the Facebook php sdk to do that. If you check out the example here:
      https://github.com/facebook/php-sdk/blob/master/examples/example.php

      and look for:
      “$session = $facebook->getSession();”

      The comment above it and the block of code below it describes to to determine if a person is logged in, and if the session is still active.

      Good luck!

      • Ellipsis says:

        Jake,

        Thank you for the quick response. Yes, I have checked that example. I have been working on this since a week now.

        Surprisingly, the $session was always null with that example.. but after I follow your oauth code. The session has been set .

        So do you recommend using your code of access token in the start when app loads for the first time and then use if( $session) to make sure user is authenticated ? for all classes(php) ?

        Cheers,
        . . .

        • Jake says:

          Well, it kind of depends on what you are doing… I would say the easiest thing is to make a graph api call to “/me” and check the response. If you get a valid response, then you are logged in, if you get an error response, then you are not.

  6. The Power of Information Review launches excellent topic very help full thanks or share

  7. Jake says:

    @Mikael, my pleasure, good luck!

  8. Mikael says:

    Thank you so much. Really appreciate your help and your quick response.

  9. Jake says:

    @Mikael, I’m sorry, I miss typed.. what you want is myObj.data[0].id
    The first property on the decoded JSON is the “data” property. Data is the array of “friends”.

  10. Mikael says:

    trace(text)

    {“data”:[{“name”:”Lorem Ipsum”,”id”:”13212720″},{“name”:”Amet Seter”,”id”:”53321042″},{“name”:”Migel Santo”,”id”:”82332728″},{“name”:”Billy Billy”,”id”:”82320801″},{“name”:”Bob Chez”… On And On

    So that seems to be working
    But after this trace statement I get the following:

    Handle Request COmplete: {“data”:[{“name”:”Lorem Ipsum”,”id”:”10732720″},{“name”:”Amet Seter”,”id”:”53201042″},{“name”:”Migel Santo”,”id”:”82332728″},{“name”:”Billy Billy”,”id”:”82332801″},{“name”:”Bob Chez”…

  11. Jake says:

    @Mikael, what do you get when you trace out the “text” variable?

  12. Mikael says:

    Actually the second gives [object object].
    Anyways I suspect some things are missing.

  13. Mikael says:

    Still can’t get this to work. I’ve left most of your code untouched and my JSON decoder in the updateResultText function.

    private function updateResultText(text:String):void{
    var myObj:Object = JSON.decode(text);
    //trace(“NAME” + myObj[0].id);
    //trace(myObj);
    }

    The first statement gives me the following error:

    TypeError: Error #1010: A term is undefined and has no properties.
    at com.app::FBTestMain/updateResultText()
    at com.app::FBTestMain/handleRequest()
    at com.jac.facebook.net::FBRequest/completeHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.net::URLLoader/onComplete()

    The second statement gives me: [object] [object]

    Any idea what’s going on?

  14. Mikael says:

    Thank you so much. I’ve been tempering with JSON but couldn’t get it to work. I’ll give it another shot.

  15. Jake says:

    @Mikael, if you go to the loader example here: https://apps.facebook.com/hookfbloaderexample/ and click the get info button, on the right you will see the returned JSON. With that you can use the JSON decoder from Adobe to turn the JSON string into an ActionScript object. That object will be an array of objects. So you can do myObj = JSON.decode(returnedString); then myObj[0].name or myObj[0].id. That will give you the name and id of the first returned friend. Hope this helps!

  16. Mikael says:

    Thanks for a great tutorial. I’m an AS3 newbie. I’ve got everything working fine. I’ve got a question about handling the return data from fb. I’m interested in getting a list of friends id:s and I can’t figure out how to do it using the code from the example.
    I can get all the friends data in as a string but I can’t figure out how to manipulate and actually make use of the data.
    I’m using the:
    _fb.fbRequest(handleRequest, “me”, “friends”);

    I’d appreciate some help on this issue or if anyone could point me to where I can get more info. I’ve spend numerous hours trying to figure this out allready.

    Thanks in advance.

  17. DoubleG says:

    Ok I’ll try that thank you Jake!

  18. Jake says:

    @DoubleG, unfortunately our library doesn’t have image uploading implemented. But you can use this library: http://code.google.com/p/facebook-actionscript-api/downloads/list to do it. Check out the media upload example. Also I have never tried uploading to a fan page gallery, but you would think it works the same as uploading to your own. Hope that helps.

  19. DoubleG says:

    Hi Jake,
    First of all, thank you very much for sharing your code with us it is very appreciated! It is my first facebook application until now and it’s going great. I have a question that maybe you can help or point me in the right direction. It is possible with the graph api to publish a picture on a “Company/Fan page gallery” Let me explain… My app load the user picture and transform it when the transformation is complete the user can publish the final result on a specific gallery on the fan page. I have read the facebook documentation about publishing photos with “/album_id/photos” but I’m not able to make it work.

    Thanks again :)

  20. Nick says:

    HI Jake.
    I posted in the original post. I am missing something. When I use your test files, everything works. I change the paths to my main swf and nothing comes up. I also changed the swf object to point to my mainswf and that opens my main swf, but i am not retrieving any variables. I did try putting in the different FacebookManager call in AS3. I am honesty a noob to all of this. Just learn php and a little java a few months ago, then got thrown into learn Fackbook API. Thanks in advance.

  21. Tim says:

    Make sure that the “Canvas Session Parameter” is also clicked, otherwise FB won’t pass it to your app.

  22. Jake says:

    @Rich, Please check to make sure you have changed the apps canvas setting to use the new OAuth Canvas authentication. Like at the very top of the post. I’m guessing that is what the issue is. If there is no access token, you get redirected.

  23. Rich says:

    Hi Jake,

    I downloaded your files, uploaded them in our server, edited some stuff to point to my facebook application and when I tried running it, it keeps on redirecting between these two URLs:

    http://apps.facebook.com/sabong_game/#access_token=...

    and

    http://www.facebook.com/connect/uiserver.php?app_id=...

    I went to your live example and it works perfectly. Am I missing some configurations in our server? Any input will greatly help.

    Thanks, thanks! Great tutorial, btw, I just wish it will work in our server as well.

    Cheers,
    Rich

  24. [...] This post was mentioned on Twitter by karannnnnnnnnnn3, Eric Snowden. Eric Snowden said: Facebook Canvas App OAuth Authentication http://goo.gl/fb/EFhLr [...]


Leave a Reply

*

Line
Line
Pony