since this article is not answering the question ( How to get user access token? ), I wanted to ask how to get the user access token.
I already have my app access token, easy. I also saw in the latest php sdk Base_facebook class there is an getUserAccesstoken function, but its useless because in the end you only get the app access token.
This is my authentification flow:
user gets into the fanpage app, and at some point, he has to authorize permissions:
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $secret,
'cookie' => true
));
$user = $facebook->getUser();
if($user == 0) {
$login_url = $facebook->getLoginUrl($params = array('scope' => "publish_stream", 'redirect_uri' => "https://www.facebook.com/pages/PAGENAME/PAGE-ID?sk=app_APP-ID0&app_data=af"));
echo ("<script> top.location.href='".$login_url."'</script>");
}
This works, fine, app_data "af" param is set to get back the page inside the fanpage app.
Because I realize, that when I remove the app, and get back to the auth page, the user cookie ($user) is still set and so the user wont be asked for permissions again.
For that reason I wanted to check permissions as well, and therefore I need the user access token
try{
$permissions = $facebook->api("/me/permissions", 'GET', array('access_token' => "$access_token" ));
}
catch (Exception $e) {echo ("<script> top.location.href='".$login_url."'</script>"); }
if( array_key_exists('publish_stream', $permissions['data'][0]) ) {
// Permission is granted!
} else {
echo ("<script> top.location.href='".$login_url."'</script>");
}
So I tried the server side auth example (https://developers.facebook.com/docs/authentication/server-side/), but of course this won't work here as you are not able to read the $_REQUEST from inside the app, so I am gonna stuck here. - How do you guys check for the permission inside an app?
$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 = "https://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.");
}
TIA & cheers,
daniel
See the section of the Facebook Developer Docs about Server-Side authentication: https://developers.facebook.com/docs/authentication/server-side/
Or you can use a hybrid client-server authentication:
http://developers.facebook.com/blog/post/534/
Related
I have several subdomains websites, and I wish to be facebook connected on each.
I've created my fb app for the main domain, and it works for it.
In each subdomains I use this link to connect (wrote by an ajax calling) :
<?php
echo "<a href=\"https://graph.facebook.com/oauth/authorize?type=user_agent&client_id=myID
&scope=email,publish_stream,status_update&redirect_uri=http://www.mydomain.com/fbConnect.php?ref=".$_SERVER['HTTP_REFERER']."\">
Connect with Facebook
</a>";
?>
My fbConnect.php
<?php
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); // Hack IE for POST params...
header("Cache-Control: no-cache");
header("Pragma: no-cache");
session_set_cookie_params(0, '/', '.mydomain.com', false); // If session is lost with subdomains...
session_start();
require('/home/....../facebook.php');
$facebook = new Facebook(array(
'appId' => 'myid',// changed for the example
'secret' => 'mysecret', // same
'cookie' => true,
));
$user = null;
$loginUrl=$facebook->getLoginUrl(
array(
'canvas' => 0,
'scope' => 'email,publish_stream,user_location'
)
);
$logoutUrl = $facebook->getLogoutUrl();
$user=$facebook->getUser();
if(!$user) echo "<script>top.location.href='".$login_url."'</script>";
if ($user) {
echo "Ok";
$user_profile = $facebook->api('/me');
$userInfo = $facebook->api("/$user");
$_SESSION['fb_id']=$userInfo['id'];
// Some stuff...
echo "<script type='text/javascript'>top.location.href = '".$_GET['ref']."';</script>";
}
?>
Scopes, connections and redirections are working, but I can't get back the $_SESSION['fb_id'] in the $_GET['ref'] page... however the session_id() is the same !
Finaly, there was some mistakes :
1. Sessions
They didn't followed in subdomains, so the trick was to change the php.ini or add ini_set("session.cookie_domain", ".myDomain.com"); (thanks #Tommy Crush)
2. redirect_uri
It seems that, in my case, it was not possible to send vars inside the redirect_uri=http://www.myDomain.com?var1=123&var2=456...
3. API use
I had to read the new beginner panel of the GRAPH API, and I was surprised by the number of changes...
I finaly used the following :
In each subdomains
// Simple link to the connection page
echo "Connect with FB";
// Record the current page whitch called this ajax
$_SESSION['connexion_ref']=$_SERVER['HTTP_REFERER'];
My new fbConnect.php
ini_set("session.cookie_domain", ".myDomain.com");
session_start();
$app_id = "myappid";
$app_secret = "myappsecret";
$my_url = "http://www.mydomain.com/fbConnect.php";
$code = $_REQUEST["code"];
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); // CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state']. "&scope=email,publish_stream,status_update,offline_access";
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['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);
$_SESSION['access_token'] = $params['access_token'];
$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
//var_dump($user);
$_SESSION['id_fb']=$user->id;
// Some stuff
// Then redirect to the subdomain page of connection
echo "<script type=\"text/javascript\">top.location.href =\"".$_SESSION['connexion_ref']."\";</script>";
}
Now it works like a charm.
I am using php-sdk for showing facebook information of the user. I have successfully shown the user profile info but while fetching any album or photos I am getting the blank data to me. I read the photos requires access_token.
Also if I put this query in the facebook graph api explorer it showing me the perfect result. So query is right may be my way of passing the url is wrong.
I am not getting the issue.
Please help.
';
$app_secret = '';
$my_url = '';
$config = array(
'appId' => '<appid>',
'secret' => '<appsecrete>',
);
$facebook = new Facebook($config);
$user_id = $facebook->getUser();
$code = $_REQUEST["code"];
if($user_id) {
//auth user
if(empty($code)) {
$dialog_url = 'https://www.facebook.com/dialog/oauth?client_id='
. $app_id . '&redirect_uri=' . urlencode($my_url) ;
echo("<script>top.location.href='" . $dialog_url . "'</script>");
}
//get user access_token
$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);
$fql_query_url = 'https://graph.facebook.com/'.'fql?q=SELECT+pid,src_small+FROM+photo+WHERE+aid+IN+(SELECT+aid+FROM+album+WHERE+owner=+me())&'.$access_token;
$fql_query_result = file_get_contents($fql_query_url);
$fql_query_obj = json_decode($fql_query_result, true);
//display results of fql query
echo '<pre>';
print_r("query results:");
print_r($fql_query_obj);
echo '</pre>';
}
?>
One parameter needs to be add for $dialog_url variable which is 'scope' which defines permissions to be given for application
$dialog_url = 'https://www.facebook.com/dialog/oauth/?client_id='.$app_id.'&redirect_uri='.urlencode($my_url).'&scope=user_photos';
echo("<script>top.location.href='" . $dialog_url . "'</script>");
for reference,
http://developers.facebook.com/docs/reference/dialogs/oauth/
Thanks
Shreyas
When a user is connected with Facebook and came on my page getUser() return 0.
I use this code:
include 'includes/php/facebook.php';
$app_id = "APP_ID";
$app_secret = "SECRET_KEY";
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
'cookie' => true
));
$user = $facebook->getUser();
if($user){
try {
$user_profile = $facebook->api('/me');
}catch(FacebookApiException $e) {
error_log($e);
}
}
When the page is loaded completely the FB.Event return "connected".
FB.Event.subscribe('auth.login', function(response) {
FB.api('/me', function(response) {
window.location.reload();
});
});
And then the page loaded twice. After this the User is connected with my page.
Is that correct, the page must loaded twice ? I think this is not user friendly. Knows someone another possibility ?
Why getUser() return 0 on the first page load ?
EDIT 2:
When I use the example from the Server-Side Authentication. And the User ist connected with Facebook, i get the user-details.
<?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.");
}
?>
When the user is not connected with Facebook, I get the dialog before i came back to my page. Can i also query the connection to facebook without the dialog ? Or can i on an other way genereate the CSRF ?
I'm not sure if you just did not post the code with which you authenticate the user, or you just don't do that part..
It's not enough to construct a Facebook object, you need to authenticate the user with facebook.
Have you read the authentication documentation?
There are two types of flows you can take, the Server-Side and Client-Side, from your code it seems like you need to use the server side flow in order to have an access token for the user on the php side, then the call for the getUser method should return the user object you want.
If I'm mistaken and you are authenticating the user, then please edit your question and add the code you use for that.
I have this facebook login code
$app_id = "xxxxxxxxxxxxxx";
$app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$my_url = "http://xxxxxxxxxxxxx";
$code = $_REQUEST["code"];
if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "https://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>");
print_r( $dialog_url);
die();
}
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 ." Create Event");
}
else {
echo("The state does not match. You may be a victim of CSRF.");
}
can I test if I am already connected to facebook website, consider it login to this page ? and no login link is being displayed ?
The question is pretty old but the answer might be helpful to others who finds similar situation. I guess, what you mean to say is to check if you code has successfully logged you to ur facebook account.
Security settings in facebook now has a feature to watch active sessions, gives you the information of when and from where have you logged in to your account. It is under:
Account Settings > Security > Active Sessions
What you can do is logout of all the sessions with end activity & finally logout of current session, then run the code. Now login via browser (or a different device, but login via browser or a different browser works fine) to see if you have got any more active sessions.
I am developing some custom iframe/canvas pages (or now known as "apps") for a Facebook business page. For my purposes, I would like to pull the users first and last name that is currently logged in (and currently likes the page) and output it on the page. This script works just fine when I am logged in as the app admin, but when I try login as my personal account or a a couple of my friends account - it seems that $session is null. Why is this happening and how do I fetch a first and last name without having the user go through any additional authentication?
<?php
require_once '../db/connect.php';
require_once '../../lib/facebook.php';
$signed_request = $_REQUEST["signed_request"];
$secret = "***********************************";
$facebook = new Facebook(array(
'appId' => '**************',
'secret' => $secret,
'cookie' => true
));
$session = $facebook->getSession();
$me = null;
// Session based API call.
if ($session) {
echo "\$session is not null!";
try {
$uid = $facebook->getUser();
$me = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
}
}
echo $me['name'];
?>
Unfortunately, this is not possible (reference):
As with a Canvas Page, you will not
receive all the user information
accessible to your app in the
signed_request until the user
authorizes your app.
So you need the user to authorize your application first, this can be found here:
<?php
$app_id = YOUR_APP_ID;
$canvas_page = YOUR_CANVAS_PAGE_URL;
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
?>
After authorizing your application and getting the User ID, the process is trivial I suppose.