Facebook App for adding tab to page OAuth in Codeigniter - php

I am creating a facebook app for adding a tab on my facebook page. I am using Codeigniter Framework for that. I need access to some user info - email, education, etc in a particular page of my app. So, I need to authenticate only in that page and get the access token. In my attempt of doing that I am able to authenticate the user but unable to get the code sent by facebook oauth, which I need to get the access token. I think this is due to the fact that Codeigniter modifies the get array. I tried some ways to get the get array working but I was still unable to get the code contents.
Can you please give me a straight forward way to get an oauth token for the user in my app. I have tried to search a lot, but nothing worked.
So far this is the code I wrote:
$canvas_page = $page_url;
$signed_request = $_REQUEST["signed_request"];
$code = $this->input->get('code');
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$auth_url = "https://www.facebook.com/dialog/oauth?client_id=" . $app_id . "&redirect_uri=" . urlencode($canvas_page)."&scope=email,user_work_history,user_education_history";
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"])."<br/>";
$token_url = "https://graph.facebook.com/oauth/access_token?". "client_id=" . $app_id . "&redirect_uri=" . urlencode($canvas_page). "&client_secret=" . $app_secret . "&code=" . $code;
$a = file_get_contents($graph_url);
var_dump($a);
}
Please give me a simple way to get the OAuth done. I want to spend more time developing that app than trying to figure out OAuth.

You may disable sanitization of GET but you probably doesn't want this.
As a quick and dirty solution you can do something like this:
parse_str($_SERVER['QUERY_STRING'], $args); // $args now contain GET parameters

Related

Accessing one's profile using Facebook's Php Sdk & Graph API

I wanted to create a small webpage in my website that shows all the activities(statuses) of ONLY my facebook account if anyone visits the page.
So I went over to the facebook developers page and downloaded the PHP SDK and started experimenting. But soon I discovered the access_token thing. This literally wasted so much of my time. Since these access token only lasted for a little time and extended access token last only for like 60 days(I don't want to keep updating them a lot). I searched everywhere, but to no avail. I couldn't find a way in which I could access only MY facebook posts with FB's PHP SDK & Graph API. Can you guys help me out with this?
You need to have YOUR access_token to fetch the feeds from YOUR account. There's no other token you can use accept this token.
So it would be easier for you if you have a backend server (which I guess you must be having). You can write a small script, where you can call the facebook login and get the normal access token, then extend it to 60 days validity and save it to your database with its expiration date. And before it's getting expired just run the script and the token will be refreshed. And your main website will always fetch the token from the database. Simple enough. I don't think there's anything else you can do.
If you are interested in such a script, I can help you with it-
$code = $_REQUEST["code"];
if(empty($code))
{
$dialog_url= "http://www.facebook.com/dialog/oauth?"
. "client_id=" . $APP_ID
. "&redirect_uri=" . urlencode( $post_login_url);
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
else
{
// access token
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $APP_ID
. "&redirect_uri=" . urlencode( $post_login_url)
. "&client_secret=" . $APP_SECRET
. "&code=" . $_REQUEST["code"];
$response1 = file_get_contents($token_url);
$params = null;
parse_str($response1, $params);
$access_token = $params['access_token'];
// extended token
$extended_token_url = "https://graph.facebook.com/oauth/access_token?"
. "grant_type=fb_exchange_token"
. "&client_id=" . $APP_ID
. "&client_secret=" . $APP_SECRET
. "&fb_exchange_token=" . $access_token;
$response2 = file_get_contents($extended_token_url);
$response2 = json_decode($response2);
$extended_access_token = $params['access_token']; // save this to the database with the expiration date(current date+60days)
}

How to get facebook user details using access token

I am creating an app in facebook and when user enters my app then the authentication will happen and after that i will get the access token and id of user now i want the details of the same user and i have to store that in database .... how to do this
CODE I HAVE TRIED IS
<?php
$app_id = "xxxxxxxxxxx";
$canvas_page = "xxxxxxxxxxxxx";
$auth_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page)."&scope=email,user_birthday";
$signed_request = $_REQUEST["signed_request"];
//print_r($signed_request);
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
//print_r($payload);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
//print_r($data);
if(!isset ($_GET['code'])) {
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
$accessToken = $data["oauth_token"];
echo ("<br/><br/>Welcome User: " . $data["user_id"]);
}
} else {
echo("<script> top.location.href='" . $pageUrl . "'</script>");
}
?>
Now i want the username and other details in string or array format ...
Please help me....
Using this Graph api :
https://graph.facebook.com/me?access_token=XXXXXXXXXXXXXXX
You can choose the fields you want returned using the fields query parameter:
https://graph.facebook.com/me?fields=id,name
You can use the Facebook PHP SDK which automatically deal with this situation and sets the access token, or you may manually specify the access token using
setAccessToken($access_token) method
and pass it your user's access token and make Graph API call using api() method to get data about user. If you want to do away with the SDK then you need to add access token as parameter to Graph API end points.

$_GET array is always empty after facebook app authentication

I am trying to play around with authentication for an app I am working on atm. The app will be tab based. I am now strugling with an infinite loop while trying to authenticate the app. The authentication procces is like this:
if (!isset($_REQUEST["code"])) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $appId . "&redirect_uri=" . urlencode($redirectUri) . "&state="
. $_SESSION['state'];
echo("<script> top.location.href='" . $dialog_url . "'</script>");
exit;
}
if ($_REQUEST['state'] == $_SESSION['state']) {
$code = $_GET["code"];
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $appId . "&redirect_uri=" . urlencode($redirectUri)
. "&client_secret=" . $appSecret . "&code=" . $code;
$response = #file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
echo("Hello " . $user->name);
} else {
echo("The state does not match. You may be a victim of CSRF.");
}
The $redirectUri is now set to "http://www.facebook.com/pages/DummyPage/PAGE_ID?sk=app_APP_ID" but once I am redirected back, after the authentication, I am unable to read $_GET or $_REQUEST arrays because they are empty (even though I can see that the url I get after auth. has "code", "state" etc. in it). This will result in infinite loop, because I am stuck in the first if statement.
What is interesting here is that when I change the $redirectUri to the url where my app sits in - right now I am testing it on localhost - so I put in "http://localhost/test/index.php" - the infinite loop wont happen because I am redirected outside facebook and I can read from $_GET array.
I need to stay on facebook when authenticating. Do you guys know how to get around this problem?
Please use the Facebook PHP SDK for things that you're trying right now.
It makes the thing a lot easier and you probably get to your goal in less time.
OR
if you want to do manually and interested in learning the internals, you need to check page tab authentication and signed request

Why is my test application in an endless redirect loop?

I am using the PHP SDK Version 3.1.1 in order to make a simple call to the Graph API. I am running it locally at http://local.fb-sandbox. The facebook application settings have the site URL set to http://local.fb-sandbox/.
I am redirected to the facebook login page and then to the page requesting my permission when I go to http://local.fb-sandbox but the application then goes into a redirect loop between a URL like:
http://local.fb-sandbox/?state=e9c091bb61afe08139af4e3b153a1e9e&code=AQBDJ4yMWVOIrukx6nRkxhNbnPH9nX6OvuqOWhVJEAgLkq6Lz27iq_-B6AIAGQ_cOpBIZktCPLLs_G5Hpt8QO5PRhDUN8l-Yu3JuT0YTzwVQiAqBlgutgia60lRT-ZzE3IHguStHq4gtuPQYJh423TBer-mB8BsqERvNsoF1L4NNe90WAWU8--MFAU3Oc4eeXyI#_=_
and
https://www.facebook.com/dialog/oauth?client_id=375741229103324&redirect_uri=http%3A%2F%2Flocal.fb-sandbox%2F%3Fstate%3Dccd13778febb68d3eb1f4763a99b2ace%26code%3DAQBFegtkch4m34-2F9KMKgScrPhWzI0qeKJlvnM6uAD81BYm2xakv0S7DEbUrNwlECrgth5-YHdT8IR_vCBzW29QMh3ecOiiEk7P03wQG2V2gaxAUsMqOOZvTl_Oq3SefiLn9BvBAPQSGXQdRSZBVdsUqDT1aZ430Lcx8Ic6axaHSyHwlkkNK5EjRhYdkjYYz0YmENk64kRf4tvmX4WrH6f4&state=19a3862962dd0422628eb7c28a832380&scope=email%2Cread_stream%2Cpublish_stream%2Cuser_photos%2Cuser_videos&fbconnect=1#_=_
I have a call to session_start() at the top of my script and have tried both with and without it. The PHP cookie is being set fine.
I've seen a lot of similar questions on here regarding this redirection loop but none of the suggested answers resolved it and they are all quite old. Should this work on localhost? AM I missing an application setting in the app settings on Facebook?
UPDATE
So it seems that if you use the code from here: http://developers.facebook.com/docs/authentication/ then it works. The php-sdk example on github completely ignores this and does not include the fact that you need to check whether 'code' is set and generate your own CSRF token. You then need to make a call to grab an access token before being able to make a call to the Graph API.
Also, the SDK's getLoginURL() method returns an https:// URL which doesn't seem to work. If I craft my own URL then it works.
WORKING CODE:
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE));
$login_url_params = array(
'scope' => 'email,read_stream,publish_stream,user_photos,user_videos',
'fbconnect' => 1,
'redirect_uri' => 'http://local.fb-sandbox/',
'state'=>$_SESSION['state']
); //using this array via the sdk does not work
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state']; //this url works
//var_dump($dialog_url);echo "<br />";
$login_url = $facebook->getLoginUrl();
//var_dump($login_url);
header("Location:{$dialog_url}");//works
//header("Location:{$login_url}");//does not work
exit;
}
if($_REQUEST['state'] == $_SESSION['state']) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$aContext = array(
'http' => array(
'proxy' => 'tcp://xxxx0:80',
'request_fulluri' => true,
),
);
$cxContext = stream_context_create($aContext);
$response = file_get_contents($token_url, FALSE, $cxContext);
$params = null;
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/me?access_token=" . $params['access_token'];
$user = json_decode(file_get_contents($graph_url, FALSE, $cxContext));
//var_dump($user);exit;
}
//var_dump($user);exit;
return $app->render('test.html',array('myvar', $user));
exit();
Note that I am going through a proxy so have to set a context for the file_get_contents() calls.
If anyone can convert my code to use the proper SDK methods and get it working (bearing in mind that I need it to work behind a proxy) then you'll get the bounty.
Many of the various server-side Facebook SDKs do not handle authentication in accordance with the documentation and recommended practices Facebook has shared over the last 3 or 4 months. You found one good example of this in how the PHP SDK uses (or doesn't use) the code parameter. There are other examples such SDKs directly reading the Facebook cookies, something Facebook engineers tell developers they should not do since the cookies are just "an implementation detail" and not something developers outside of Facebook should be building dependencies on.
I am not sure where you got that code in your working code example, but I couldn't find any support for including parameters such as fbconnect=1
So given that the SDK is not implementing authentication as per Facebook recommendations and documentation, and that Facebook has provided a complete PHP implementation in their documentation, I recommend you just use the version Facebook provides, copy and pasted here for your reference from this page http://developers.facebook.com/docs/authentication/ :
<?php
$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET";
$my_url = "YOUR_URL";
session_start();
$code = $_REQUEST["code"];
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state'];
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if($_REQUEST['state'] == $_SESSION['state']) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = #file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
echo("Hello " . $user->name);
}
else {
echo("The state does not match. You may be a victim of CSRF.");
}
?>
There are several problems with this.
Your redirect_uri should be like http://local.fb-sandbox/ . There must be a trailing slash at the end - both in the code and the facebook app settings in developers.facebook.com.
You have to user uurlencode on the redirect_uri.
Don't use $_SERVER['REQUEST_URI'] in the redirect_uri. Find a way to add any parameters you need by processing app_data or adding them depending on your user journey.
As a start replace this line:
'redirect_uri' => urlencode('http://local.fb-sandbox/'),
and experiment with adding parameters later.

Facebook Graph API call successfully returns my user information, but not my albums?

The question is: is it my brain? Or Facebook's infuriating API?
Intention:
Return my facebook album information and my user information
result: empty data set for album information, full result's for user information
{
"data": [
]
}
<?php
/****************************************************************************
Application settings
****************************************************************************/
$app_id = '123456';
$app_secret = "4543163864";
$my_url = "http://www.myurl.com/app";
$canvas_page = 'http://apps.facebook.com/my_canvas_page/';
# authorize the user using oauth protocol (including required permissions)
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page)."&scope=user_photos,friends_photos";
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$fb_user_session = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
# if authorization failed, kick back to auth_url
if (empty($fb_user_session["user_id"]))
{
echo("<script> top.location.href='" . $auth_url . "'</script>");
}
else
{
/****************************************************************************
User successfully logged in.
****************************************************************************/
$my_albums = "https://graph.facebook.com/me/albums?access_token=".$fb_user_session['oauth_token'];
$my_info = "https://graph.facebook.com/me?access_token=".$fb_user_session['oauth_token'];
echo "<a href='$my_albums'>my album information</a><br>";
echo "<a href='$my_info'>my user information</a>";
### ignore this, just testing iframe call ###
exit;
echo("<script> top.location.href='" . $my_albums . "'</script>");
}
?>
Additional information:
Testing an 'album' request from http://developers.facebook.com/docs/reference/api/user/ while logged in works! It successfully returns all my album info. But I noticed the authorization token in the test URL is different from my retrieved application token ($fb_user_session['oauth_token']). What is going on here?
Am I missing some kind of authorization step? Why would my application return empty data for my albums using the exact same call & token while Facebook's test call returns a full set? If anyone can help solve this problem once and for all, that would be awesome.
Any ideas?
Try adding "user_photo_video_tags" to the list of scopes requested. Also, try calling the permissions api call to make sure you have access to the user's photos by checking the "user_photos" permission.
The url is: https://graph.facebook.com/me/permissions?access_token=...

Categories