Getting user info inside tab using Facebook SDK 4 - php

I was wondering if it is possible to get the name or email of the user inside a Facebook page tab.
I've been trying to do this for quite some time now, and can't seem to get it.
It was quite easy with the old SDK, but with this one I need the FacebookRequest(), which I can only get after the getSessionFromRedirect().
Now the real problem is when I redirect the user back to Facebook I lose the Session.
The code:
session_start();
define('BASE', 'http://www.example.com/');
define('APP_ID', '123456789');
define('APP_SECRET', 'qwerty');
define('FB_TAB', '//www.facebook.com/example?sk=app_' . APP_ID);
foreach (glob('Facebook/*.php') as $filename) { require_once $filename; }
use Facebook\FacebookSession;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookRequestException;
if(isset($_SESSION['fb_session']) && !empty($_SESSION['fb_session']))
{
// if already logged print user info
$user_profile = (new FacebookRequest(
$_SESSION['fb_session'], 'GET', '/me'
))->execute()->getGraphObject(GraphUser::className());
echo 'Name: ' . $user_profile->getName(); die;
}
else
{
// otherwise redirect user to login
try {
FacebookSession::setDefaultApplication(APP_ID, APP_SECRET);
$helper = new FacebookRedirectLoginHelper(BASE);
$session = $helper->getSessionFromRedirect();
if($session)
{
// if has token save into session to use later
$_SESSION['fb_session'] = $session;
header('Location: ' . FB_TAB);
}
else
{
// get Facebook login url
echo '<script>top.location.href = "'.$helper->getLoginUrl().'";</script>'; die;
}
}
catch(FacebookRequestException $e) { var_dump($e); }
catch(\Exception $e) { var_dump($e); }
}
Explaining by steps:
As we enter the Facebook page tab, I check for the $_SESSION. Because it's the first time I can't find it, so I redirect the user to the Facebook login (getLoginUrl).
As we exit the page tab I get the object through (getSessionFromRedirect) and save it in the $_SESSION. So far so good. The problem resides here, after I save the $_SESSION I redirect the user back to the Facebook page tab (This is where it get's tricky).
When the user enters the page tab, we're suppose to have the object inside the $_SESSION, but it is gone.
So the questions is...
Using the SDK 4, is there any way to solve this? or does anyone know a way to get the user information without getting this FacebookSession?
Thanks :)

Related

Facebook PHP SDK v4.0.0: $session is not set even after authorizing facebook from the login URL

UPDATE: The problem is now solved. All what I did is to put this code in a different php file:
<?php
Function __autoload($classname) {
$filename = "./".$classname .".php";
require_once($filename);
}
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;
session_start();
FacebookSession::setDefaultApplication('257772307761170','***');
$helper = new FacebookRedirectLoginHelper('http://localhost/parqueeste/login.php');
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(\Exception $ex) {
// When validation fails or other local issues
}
if ($session) {
echo 'Yeah!!';
}
?>
Original message: I'm using the Facebook SDK v4.0.0 for PHP to create a "Login through Facebook". But even after the user clicks the login URL, the $session variable is not defined so I can't access the user's data. Here's my code:
<?php
session_start();
function __autoload($classname) {
$filename = "./".$classname .".php";
require_once($filename);
}
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;
FacebookSession::setDefaultApplication('257772307761170','****'); //I have the right
app secret on my code, of course.
$helper = new FacebookRedirectLoginHelper('http://localhost/parqueeste/');
$loginUrl = $helper->getLoginUrl();
if(isset($session) AND $session) { // <--- I use isset() so I don't
get a warning everytime I load my site
try {
$user_profile = (new FacebookRequest(
$session, 'GET', '/me'
))->execute()->getGraphObject(GraphUser::className());
echo "Name: " . $user_profile->getName();
} catch(FacebookRequestException $e) {
echo "Exception occured, code: " . $e->getCode();
echo " with message: " . $e->getMessage();
}
}
?>
Thanks in advance!
The actual issue here is that when you call the getLoginUrl() method e.g
$helper = new FacebookRedirectLoginHelper('http://localhost/parqueeste/');
$loginUrl = $helper->getLoginUrl();
It changes the state variable. In your original question (before you edited it to include your fix) you called this method before you validate the response in your original code, it then invalidates the CSRF check and in short says the user hasn't logged in. I ran into this exact same issue, and the best bet is to either have a separate login page as you have done here. Or to have the login url generated after you've done all the checks for a valid session/graphobject response.
Hope this helps some else who has the same issue as it annoyed me for days and isn't really documented and is a big change from the previous api. You need to look through the SDK to see what's going on
I experienced this issue myself. You need to start a session using session_start(); in your script for it to work correctly. See my short tutorial for more information.
Add it to the top of you script, I did it just after the use statements.

Facebook PHP API giving inconsistent results when used inside <div>

I am working with both the Facebook PHP SDK and the Facebook JS SDK (using the JS SDK to handle login only, much as is discussed here: https://developers.facebook.com/blog/post/534/).
I have a custom button that I have created and attached to the FB.login() function. My goal is to have the text inside that button say "Log in with Facebook" if the user is not logged in, and to the text inside the button display the user's name if they are logged in.
The problem is that when I try to refer to the $user_profile variable that has the logged in user's information, it works when I use it outside the button, but says that the variable is not set when it is used inside the button (code below). What could be causing this?
<?php
// Get the contents of static-head.html to open the HTML doc:
readfile("static-head.html");
// Include the Facebook PHP SDK so that we can have people login
require_once('fb/facebook.php');
$config = array(
'appId' => 'MY_APP_ID',
'secret' => 'MY_APP_SECRET',
'allowSignedRequest' => false
);
$facebook = new Facebook($config);
$user_id = $facebook->getUser();
// Get Facebook Login information
if($user_id) {
// We have a user ID, so probably a logged in user.
// If not, we'll get an exception, which we handle below.
try {
$user_profile = $facebook->api('/me','GET');
// If this doesn't throw an error, we now we have a $user_profile that we can use
} catch(FacebookApiException $e) {
// If the user is logged out, you can have a user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll just wait for the user to log in.
error_log($e->getType());
error_log($e->getMessage());
// Set the $user_id to NULL so that there's no confusion elsewhere in the app.
$user_id = NULL;
}
} else {
// Let the user log in through the JavaScript SDK
}
// Just to prove that $user_profile is being recognized:
// ***This works! It returns "Chris"
echo $user_profile['first_name'];
// Function to set the text inside the LogIn/LogOut button:
// ***This doesn't work! It returns "Log in with Facebook"
function getLogInLogOutText(){
if(isset($user_profile)){
return $user_profile['first_name'];
} else{
return 'Log in with Facebook';
}
}
?>
<div id="userLogInLogOut" class="uiControlsDivs">
<button id="userLogInLogOutButton"><?php echo getLogInLogOutText(); ?></button>
</div>
I am utterly confused how this is possible. On one line, the code works and returns the Facebook user's name. Then, just a few lines later, it doesn't work! What is going on?!
Thanks for any help you might be able to provide!
Try parsing the variable to the function, so say make the function:
function getLogInOutText() { ...
into
function getLogInOutText($user_profile) { ...
and call with with that, i.e. :
<?php echo getLogInOutText($user_profile); ?>
Not sure it will work, but it's worth a test. Otherwise try making it a global variable:
PHP reference for variables scope - http://www.php.net/manual/en/language.variables.scope.php

Facebook PHP SDK returning user ID even after logout

I'm using the FB PHP SDK to log users in. Nothing fancy here - just calling $fb->getLoginUrl() to generate the login link, user goes through to it, authorises, is bounced back to my site and they're logged in. So far, so good.
On a page reserveed for logged-in users I have this code:
echo $fb->getUser(); //supposedly outputs user ID or 0 on failure
But the thing is it outputs the user ID even if I've gone to Facebook manually and logged out of it. It never seems to output 0 for me, i.e. detects that I'm logged out.
What am I missing? Is there a better way to detect login status?
(Note: the JS SDK is not an option for me)
Try using the destroySession method and also kill the session variable when you want to logout.
include('fb-php-sdk/facebook.php');
$config = array();
$config['appId'] = '641xxxx559';
$config['secret'] = '3bxxxxxxcd1c';
$facebook = new Facebook($config);
if(isset($_GET['act']) && $_GET['act'] == "logout") {
$facebook->destroySession();
// destroy session var here. Should be in format of "fmb_$appID"
}
$user = $facebook->getUser();
echo $user;
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
echo "<pre>";
print_r($user_profile);
echo "</pre>";
$logout = $facebook->getLogoutUrl();
//echo $logout;
echo "<a href='test.php?act=logout'>Logout</a>";
} else {
$login = $facebook->getLoginUrl(array("scope"=>"email","display"=>"popup","redirect_uri"=>"http://domain.com/test.php"));
echo "<a href='".$login."'>Login</a>";
}
As you can see I am passing the scope key in the params array to request what I want back. The first time this is run the user will be asked by facebook to confirm what ever is being asked for in the scope.

Facebook PHP SDK Connection

I've been searching this site for the answer for a while and I haven't been able to find one for this problem so I'm hoping someone can give me a hand. I'm not exactly an experience PHP programmer so there could be something severely wrong with what I'm doing.
Anyways I am working with another developer who doesn't code in PHP at all and needs access to Facebook information. That being said I'm trying to develop a facebook class which encapsulates all of the Facebook graph calls, allowing for my buddy to call a single function and get all of the information he needs without having to worry about any of the Facebook PHP SDK functions at all. This class I've put in a separate file called CFacebook.php. The code for this class can be found below (I've simply copied the example off of the facebook website)
<?php
require_once 'facebook.php';
class CFacebook
{
//private variables
private $Config = "";
private $FBObject = "";
private $Code = "";
private $Session = "";
private $AppId = '*************';
private $ApiSecret = '*******************';
//I have the API secret and AppID in
//here but for privacy reasons I've taken them out
//constructor
public function CFacebook()
{
$this->FBObject = new Facebook();
$this->FBObject->setApiSecret($this->ApiSecret);
$this->FBObject->setAppId($this->AppId);
}
//Get profile information
public function GetFBProfileInformation()
{
$FBProfile = "";
$ID = $this->FBObject->getUser();
echo "<br />";
if($ID)
{
try {
$FBProfile = $this->FBObject->api('/me','GET');
return $FBProfile;
}catch (FacebookApiException $e)
{
//send back to UI to have user sign in
// If the user is logged out, you can have a
// user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll
// just ask the user to login again here.
echo "has ID <br />";
$login_url = $this->FBObject->getLoginUrl();
echo 'Please login.';
echo $this->FBObject->getAccessToken()."<br />";
echo $this->FBObject->getApiSecret()."<br />";
error_log($e->getType());
error_log($e->getMessage());
}
}else
{
//return to UI taht user isn't logged in and have user re-sign in
//If the user is logged out, you can have a
// user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll
// just ask the user to login again here.
$Page = "http://fratlabs.com/FacebookTest.php";
$login_url = $this->FBObject->getLoginUrl(array('scope'=>'email,publish_stream,user_likes,user_hometown','redirect_uri'=>$Page));
//$logout_url = $this->FBObject->getLogoutUrl(array('next'=>'http://fratlabs.com/FacebookTest.php'));
echo 'Please login.';
//echo 'Logout Url: Logout';
error_log($e->getType());
error_log($e->getMessage());
}
//echo $this->FBObject->getLogoutUrl(array('next'=>'http://fratlabs.com/FacebookTest.php'));
}
};
?>
This class is included and instantiated in a test page which is where the Facebook login is returned too. Maybe I need to include all of these calls in the same page as the one the facebook login is returned to? The only thing that is confusing me is that once every blue moon the code will work and I will actually create a link to Facebook, but every other time I'm left staring at the login page with the "please login" link on it.
While I am not a php expert myself, I believe it is advised to use try/catch objects for catching exceptions usually as message output not as a logic operator (like if/else) with well-defined pathways of the script like you seem to do. Consider a different approach like initializing the fb session and authenticating the user in the first class and presenting the user information in a second class. But for your partner who only wants fb user info, a message can be delivered in second class if user did not successfully login or authenticate.
For illustration (without functions), I use the code included here.

PHP HybridAuth: How to redirect to the "Allow" page of the selected social network?

I'm having some issues with HybridAuth when I need to redirect "a non-registered user in my local database", to the selected social network: facebook, twitter, windows live, linkedin, openid, etc, more presiously to the "Allow" and "Cancel" page!?
Till now I've got this code going on:
try {
// $via for instance can be: Twitter, Facebook, etc
$hybridauth = new Hybrid_Auth( $myConfig );
$via = ucfirst($via);
$adapter = $hybridauth->authenticate( $via ); // from this line some redirecting accoures
if( $hybridauth->isConnectedWith( $via ) ){
$user = $hybridauth->authenticate($via)->getUserProfile();
}
$profile = Users::model()->findByAttributes(array(
'networkName' => $via,
'networkId' => $user->identifier,
));
if(!is_null($profile)) {
// do a login
} else {
// do a registration + login
}
} catch(Exception $e) {
echo "Error: please try again!";
echo "Original error message: " . $e->getMessage();
die();
}
I hope I've made my point clear. Thanks for all assistance in this matter!
The way I do is to store the provider and the provider identifier in a database, which seems to be the way you implemented as well.
If the user does not exist, I create it and then redirect the user to the user profile editor. Otherwise I just redirect to the main page or dashboard.
The provider data has all the required fields for creating a basic profile. If you need something else, redirect the user to a page with a form for him to complete the registration. Store anything else you need in SESSION or similar. You can use $hybridauth->restoreSessionData($_SESSION['HYBRID']) to keep the session on.

Categories