Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Simple FB App in PHP

Status
Not open for further replies.

Leozack

MIS
Oct 25, 2002
867
GB
Hi guys - thought I'd try an experiment in fb app. It certainly seems to have changed a LOT in the last 5y if old online tutorials are anything to go by!
My current code looks like this - with example id's. My current issue is where am I supposed to get the "userid" from to compare against in the token? /confused

I've somewhat bungled my way through with trial & error and code lookups from and so far, and I'm not using the fb API - though if I should be, say so.

This whole project may be irrelevant since now you need SSL for a fb app so I'd have to buy one grrrrr - in the mentime I'm testing via the canvas link directly (using fb link gives blank page, presumably cos no ssl?)

PHP:
$appid = 987654321;
$appsecret = "1a2s3d4f5g6h7j8k9l0";
$canvasurl = "[URL unfurl="true"]http://www.webpage.com/app/";[/URL]
$userid = "123456789";	// temp set userid to you - how do I actually get the userID I'm testin the token against?!

// -------------------------------------- GET FB TOKEN
$app_id = $appid;
$canvas_page = $canvasurl;
$auth_url = "[URL unfurl="true"]https://www.facebook.com/dialog/oauth?client_id=".$app_id."&redirect_uri=".urlencode($canvas_page);[/URL]
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
echo "<br>$data";
if (empty($_GET['code'])) { //data["user_id"])) {
	//echo "no user id!  doh";
	echo("<html><head></head><body><script> top.location.href='" . $auth_url . "'</script></body></html>");
} else {
	//echo ("Welcome User: " . $data["user_id"]);
}

// -------------------------------------- IF USER DECLINES LOGON
if ($_GET['error_reason']) {
	?>
<html><head></head>
<body><h1>Error - <? echo $_GET['error_description']; ?></h1></body>
</html>
	<?
	exit();
}

// -------------------------------------- IF FB TOKEN - VALIDATE IT
if ($_GET['code']) {
	$token = file_get_contents("[URL unfurl="true"]https://graph.facebook.com/oauth/access_token?client_id=".$appid."&redirect_uri=".$canvasurl."&client_secret=".$appsecret."&code=".$_GET[/URL]['code']);
	//print_r($token);
	$tokentmp = explode("&",$token);
	$token = $tokentmp[0];
	$tokenexpires = $tokentmp[1];
	$tokentmp = explode("=",$token);
	$token = $tokentmp[1];
	$tokentmp = explode("=",$tokenexpires);
	$tokenexpires = $tokentmp[1];
	//echo $token." valid for ".(($tokenexpires/60)/60)." hours<br>";

	$apptoken = file_get_contents("[URL unfurl="true"]https://graph.facebook.com/oauth/access_token?client_id=".$appid."&client_secret=".$appsecret."&grant_type=client_credentials");[/URL]	
	$apptokentmp = explode("=",$apptoken);
	$apptoken = $apptokentmp[1];
	//echo $apptoken;
	$inspectedtoken = file_get_contents("[URL unfurl="true"]https://graph.facebook.com/debug_token?input_token=".$token."&access_token=".$apptoken);[/URL]
	//$inspectedtoken = file_get_contents("graph.facebook.com/me?access_token=".$token);
	//print_r($inspectedtoken);
	$json = json_decode($inspectedtoken, true);
	//print_r($json[data]);
	
	if ($json[data][user_id] == $userid) { echo "User confirmed<br>"; }
	if ($json[data][app_id] == $appid) { echo "App confirmed<br>"; }
	//exit();
}

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
isn't the idea that the userid is something you generate and store in your application and then add the token to the table as a lookup?

or if you mean the user_id from within facebook, I understand that this is contained in the signed_request element of the relevant superglobal. this is passed to your app after it is allowed by a user in a canvas app (i.e. from within facebook rather than using facebook as a logon to an external app).

i'm note sure about this
Code:
if (empty($_GET['code'])) { //data["user_id"])) {

why would there be a 'code' element in the GET superglobal?

i'd test instead for $data['user_id']
 
You're right it was $data['user_id'] - part of the tutorial code on fb site - but what happened? I watched the URL bar changing every second to a new ?code=blablabla for like 200 chars of blabla so I figured I need to see when there is a 'code' being given and go from there, which I do. Unfortunately most of this is still going above my head so I'm just hitting things until I move it forwards an inch. This all seems rather messy and brutish compared to what for most people must be simple and pre-existing code to just say "here you are on my app page - get them to auth the app for use - verify the auth is by them and by my app, do appy things". It'll be a while at this rate before I get to actually do appy things, so to speak :/

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
Rereading your reply I'm not following - yes fb passes your app the token (in the 'code' GET data) that includes the user ID when run through more fb calls, but it says to check it is the right appid and userid that you were expecting. My problem is well what userid are you supposed to check it against if it's the only one you've got?

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
the one that you stored in your user database. obviously you have to take fb on faith for the first use by a user.
 
Well when they first load your app they don't exist in your app - and your app is just like "hello this apparent person - lets start doing stuff"?

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
yes. but there will be an authentication event each time the user accesses your app.
internally you should validate that the user is who you expect (particularly if you offer alternate channels to your app outside of Facebook)
 
Pretty sure this app will only run inside fb to keep things simple - allegedly - means the user accounts and authentication should be handled for me. However this is feeling really tricky just to do the equivalent of a quick php encrypted pass lookup against a db. But then the only place I find this method is the fb dev site. Everywhere else has really simple code using php api it seems. Maybe I should try to stick that on my host and use that instead? eg $user = new facebook(); or whatever.

_________________________________
Leozack
Code:
MakeUniverse($infinity,1,42);
 
can we step back a bit?

let's assume you are building a canvas app. and let's assume that you will store information about a user's state interacting with you app.

as i understand it there is a flow.

when a person clicks on your app for the first time you will not know who they are. fb will post some data to you site url and this data will be in the signed_request param.

Code:
function decodeRequest($request){
  list($encoded_sig, $payload) = explode('.', $signed_request, 2); 
  return json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
}

if(isset($_POST['signed_request'])):
 $data = decodeRequest($_POST['signed_request']);
else:
 //probably in the game state so take appropriate action based on other parameters.
endif;
....

if you do not yet know the user then there will be no user_id passed. and you act on this information to flash a dialog at the user. if the user accepts the auth you will be sent a code. you then have to exchange that code server-to-server for an access token. you can then use that access token to access the other apis that allow you information on the user and to interact with the user's timeline.

the php sdk may be a better starting point than rolling your own code. but here is a small snip of how i see the process working.

Code:
function redirectUser($url){
 echo <<<HTML
<script>
top.location.href='$url';
</script>
HTML;
exit;
}
 //... carrying on from previous code

$appID = 'my app id on facebook';
$canvasUrl = 'my app url';
$mySecret = 'my secret code';

if(isset($_REQUEST['signed_request'])):
 $data = decodeRequest($_REQUEST['signed_request']);
 //check if we know user already
 if(isset($data['user_id'])):
   $user = new user($data['user_id']);
   if(!$user->isKnown()):
    $user->save();
    //now show a form to capture some other information that you need about the user 
   endif;
 elseif(isset($_GET['code'])):
   //need to take the code and exchange for an access token
   //see documentation
 else:
   //need to redirect user to a facebook auth page
   $url = sprintf("[URL unfurl="true"]https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s&response_type=%s",[/URL] $appID, urlencode($canvasURL),'code');
   redirectUser($url);
 endif;

else:
 //probably in the game state so take appropriate action based on other parameters.
endif;

NB. above is not tested and i have not looked up all the message api to be sure of each response from endpoint.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top