Authorizing Iframe Facebook Applications For Graph API
This article continues my exploration of best facebook graph api integration into your flash app. Before continue reading, make sure you understand the previous article. Due to huge interest, I am adding codes that makes your flash app working with graph api within facebook iframe. Try this app live on http://apps.facebook.com/blogoauthgraph/, notice once you get there, you are redirected to grant permissions (if not authorized or granted already) and then redirected back to the app, where you are connected and ready to use graph api.
What I did was changing one line of ActionScript, I added autoConnect() methods that sends app flashvars directly into FacebookOAuthGraph object.
var facebook:FacebookOAuthGraph = new FacebookOAuthGraph(); ... facebook.autoConnect(parameters); // passing flashvars
See full ActionScript code for details.
Now there is a different html wrapper for facebook iframe – facebook.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="cs" xml:lang="cs"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-language" content="cs" /> <title>FacebookOAuthGraphTest</title> <script type="text/javascript" src="js/swfobject.js"></script> <script type="text/javascript"> //<![CDATA[ function allRequestParameters() { var data = {}; var strHref = window.location.href; if ( strHref.indexOf("?") > -1 ) { var strQueryString = strHref.substr(strHref.indexOf("?")+1); var aQueryString = strQueryString.split("&"); for ( var iParam = 0; iParam < aQueryString.length; iParam++ ) { var aParam = aQueryString[iParam].split("="); data[aParam[0]] = aParam[1]; } } return data; } function generateFlash() { var flashvars = allRequestParameters(); flashvars.session = '{"access_token":"' + signed_request.oauth_token + '"}'; var params = { allowScriptAccess: "sameDomain" }; var attributes = { id: "FacebookOAuthGraphTest", name: "FacebookOAuthGraphTest" }; swfobject.embedSWF("FacebookOAuthGraphTest.swf?v=2", "alternative", "100%", "100%", "10.0.0", "expressInstall.swf", flashvars, params, attributes); } <?php $signed_request = $_REQUEST["signed_request"]; list($encoded_sig, $payload) = explode('.', $signed_request, 2); $data = base64_decode(strtr($payload, '-_', '+/')); echo "var signed_request=" . $data . ";"; ?> if(!signed_request.oauth_token){ window.top.location = "https://www.facebook.com/dialog/oauth" + "?client_id=" + '268718683475' + "&redirect_uri=" + 'http://apps.facebook.com/blogoauthgraph/' + "&scope=publish_stream,user_photos,user_photo_video_tags" + "&response_type=token"; }else{ generateFlash(); } //]]> </script> <style> body {margin:0px;overflow:hidden} html, body, object, embed {width:100%;height:100%;outline:none;} </style> </head> <body style="text-align:center;"> <div id="alternative"> <a href="http://www.adobe.com/go/getflashplayer"> <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /> </a> </div> </body> </html>
There are few lines of code to be mentioned:
getRequestParameter(name) – returns GET parameter from iframe url, you can use your own functions- allRequestParameters() – returns object consisting of all iframe GET parameters, used to pass flashvars into our flash
- php code to define javascript signed_request variable containing valid token
- window.top.location – if there is no token parameter found (not authorized yet), you are redirected to the facebook authorization. Do not forget to change client_id and redirect_uri when using for your app.
Facebook settings:
App ID: 268718683475 Site URL: http://blog.yoz.sk/examples/FacebookOAuthGraph/ Site Domain: yoz.sk Canvas Page: http://apps.facebook.com/blogoauthgraph/ Canvas URL: http://blog.yoz.sk/examples/FacebookOAuthGraph/facebook.php?a=b Canvas FBML/iframe: iframe Disable Deprecated Auth Methods: Enabled Stream post URL security: Disabled OAuth 2.0 for Canvas: Enabled POST for Canvas: Enabled Canvas Session Parameter (Deprecated): Disabled November 2010 Rollup: Enabled Timezone-less events: Enabled Upgrade to Requests 2.0: Enabled JSON Encoding Empty Arrays: Enabled
Here is the final facebook app http://apps.facebook.com/blogoauthgraph/
updated Jul 21, 2010: Quickfix for late facebook changes:
updated Jul 22, 2010: Facebook rollbacked the change and added “Canvas Session Parameter” parameter in facebook app settings / Migrations tab. With this setting enabled, your apps should work normally as they previously did.
updated Mar 16, 2011: Catching token from POST parameter.
please solve issue
http://www.adobe.com/devnet/facebook/samples.html
at sample3
issue:- album length showing 0
please let me know how to connect facebook and access its album in flex give me example with source code
I Jozef,
you will say that I have always problem with Internet Explorer… But when I test http://apps.facebook.com/blogoauthgraph/ on IE, there is a flash error in autoConnect(…) function : “var session:Object = JSON.decode(parameters.session);” doesn’t work ==> it’s impossible to get the value of parameters.session
Do you have an idea why the flashvar in .js is correctly get in Firefox and Chrome but not with IE ?
Thanks in advance.
Garcimore
I Jozef,
Sorry for my last comment, in fact it’s not a problem of flashvars getting with IE… but a problem of flashvars encoding in the javascript code.
I suggest that you update your facebook.php :
– in the generateFlash() function : flashvars.session = encodeURIComponent(‘{“access_token”:”‘ + signed_request.oauth_token + ‘”}’);
With this change the autoconnect will work with IE, 😉
Best regards.
Garcimore.
thank you for solution Garcimore
Right now this is my favorite page on the internet. Thank you all!!
I can’t get this new auth to work. I don’t understand how I’m supposed to extract the top.location access_token hash when the app is inside an iframe. Also, I tried the PHP $signed_request method and it always comes up empty. I have “Oauth 2 for Canvas” and “POST for Canvas” enabled. No matter what I try, I can’t get to the access_token. What am I missing here?
hi Bill.
– you do not extract nothing from top.location, you pass there url to get authorized
– if you have correct facebook setting (see the ones from me) you should get some authorization info in POST variables. make sure yor server support _POST variable
Hi Jozef,
My client’s server accepts _POST vars because when I use FB’s technique:
<?php
$app_id = YOUR_APP_ID;
$app_secret = "YOUR_APP_SECRET";
$my_url = "YOUR_URL";
$code = $_REQUEST["code"];
if(empty($code)) {
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url);
echo(" top.location.href='” . $dialog_url . “‘”);
}
$token_url = “https://graph.facebook.com/oauth/access_token?client_id=”
. $app_id . “&redirect_uri=” . urlencode($my_url) . “&client_secret=”
. $app_secret . “&code=” . $code;
$access_token = file_get_contents($token_url);
$graph_url = “https://graph.facebook.com/me?” . $access_token;
$user = json_decode(file_get_contents($graph_url));
echo(“Hello ” . $user->name);
?>
I am able to get $code, but unable to get file_get_contents($token_url); to work because (I’m assuming) the $token_url is secure.
However, when I use your technique I am never able to get $signed_request either with $_REQUEST[“signed_request”] or $_POST[“signed_request”]. So, I’m stuck with a looping app.
Also, I don’t understand how your post “neverending facebook changes…” applies to this. They seem like 2 different techniques.
I greatly appreciate any light you can shed on this.
Thx,
WL
http://apps.facebook.com/sambazon_warrior_up
request to http://apps.facebook.com/sambazon_warrior_up :
POST /fbapp/ HTTP/1.1
Host: sambazon.com
Referer: http://apps.facebook.com/sambazon_warrior_up/
signed_request=N7GgX95r…
asi you can see, there surely is post parameter available!
Now I’m even more perplexed. I can now see the signed_request variable and am able to parse the oauth_token out of it, but I’m still seeing the page constantly refresh itself… even if I remove the generateFlash() function. On Chrome it just repeats. On Firefox it throws up “Object Moved”. Here is my PHP:
BTW: I am not able to create the signed_request var like your example. The initial var signed_request=; throws up an error in my JS console.
Sorry, guess the PHP got consumed:
$app_uri = “http://apps.facebook.com/sambazon_warrior_up/”;
$auth_uri = “https://www.facebook.com/dialog/oauth”;
$client_id = “[my id]”;
$scope = “publish_stream,user_photos,user_photo_video_tags”;
$signed_request = $_POST[“signed_request”];
list($encoded_sig, $payload) = explode(‘.’, $signed_request, 2);
$data = base64_decode(strtr($payload, ‘-_’, ‘+/’));
if(empty($signed_request)){
echo ( “window.top.location = ‘” . $auth_uri .
“?client_id=” . $client_id .
“&redirect_uri=” . urlencode($app_uri) .
“&scope=” . $scope .
“&response_type=token’;”);
}else{
echo “var signed_request=” . $data . “;”;
echo “generateFlash();”;
}
Yikes! Sorry for all the frustration. The root problem was that I hadn’t included the www in the site’s app url. The client redirects when it is missing. The redirect then caused the POST data to disappear.
Thanks for all your help!
Hi Jozef,
I discover something strange…
Concerning as3 graph api iframe embeding exemples from facebook-actionscript-api google code (wich are working fine) :
On firefox 3.6.12 and previous, the auto init (auto connect) is not working. The app will work outside of FB but not in the canvas.
But if you set a setTimeout (even with no delay) before the embed swf function….. it works !!
I know that doesn’t concern your own embeding solution but the facebook-actionscript-api one.
However, perhaps yours have the same kind of issue on on 3.6.12 and previous.
hi Etienne,
glad you made it work. its really interesting that it does not work correctly with ff. it may be due to flash app is not completely prepared. not sure what may case the issue:
– missing flashvars?
– shared object not ready?
– stage and urlloader not ready?