facebook php logout issue - php

I have been using this code for facebook sdk logout but its not working. However i can login iwth it successfully. Here is the code.
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
}
else {
$loginUrl = $facebook->getLoginUrl(array(
'scope' => 'user_about_me, user_hometown')
);
}
?>
<?php if ($user){ ?>
Logout Here
<?php }else{ ?>
Login with Facebook
<?php }?>

The default Facebook SDK uses php's built in session implementation to store it's data. Among these the last logged in user id.
When your user clicks on the logout link, facebook will log her out, and send her back to your site, however facebook can't delete the values in your site's $_SESSION. Add a next parameter to the $facebook->getLogoutUrl() so facebook will send the user back there, and you can clear the whole session (after all the user has logged out) with session_destroy.
If you don't want to clear the whole session just the facebook specific values, there's a method for that called destroySession on the BaseFacebook class (for some reason not listed in offical sdk docs).

Related

Check if Facebook user is logged in to app with PHP SDK

I have an app using the Facebook Login API. I take the details of the user and store it in my own database and create my own user id for the user (I also store the facebook id).
Next time the user visits my site, I want to automatically set the session, without having them reconnecting again. So I want to get the Facebook ID of the user (If he is already authenticated) and then check in my database if that ID exists, if so then I set the session.
This is described in the Javascript SDK, however the problem with the Javascript SDK is that the user will not be logged in when visiting the first page, only after a page refresh (Since the Javascript is run after the PHP is executed, so the session is not set when the page loads).
So I want to do this server side, using the PHP SDK.
I tried the following code:
public function isUserLoggedIn(){
$facebook = new Facebook();
$user = $facebook->facebook->getUser();
if($user){
//Use API call for /me which require authentication
try{
$me = $facebook->facebook->api('/me');
//If id_facebook exist, then set logged in session to user id
if($me){
$stmt = $GLOBALS['link']->prepare('SELECT * FROM users WHERE id_facebook=:id_facebook');
$stmt->execute(array('id_facebook' => $me['id']));
if($row = $stmt->fetch()){
$_SESSION['uid'] = $row['id'];
}
}
} catch (FacebookApiException $e) {
$user = null;
//User is not logged in
}
}
}
This code only passes when the Javascript SDK has already authenticated the user and he is logged in. It does not work as intended.
So:
How do I use the PHP SDK to check if the user is authenticated with my App?
I could just set a $_COOKIE myself, is that the way to do it? I suppose that there is an "official" way using the SDK/API, since there is with the Javascript SDK.
I feel I'm a bit late, but here's my two cents:
I log into SO using facebook. Sometimes, in fact, after a day or so passed, i land on this site and after a second or two a little popup tells me that I've been logged in and to refresh the page. It's not really an issue, I just reload the page and I'm happy. That's what you're referring to.
But remember, should you only check the session to retrieve user's ID and facebook data, could lead to problems when the users logged out from facebook (or from your app): your session is not up-to-date with facebook.
That's why using Javascript SDK to login should be better.
I've done a lot of tests and trials today, to understand how the whole thing works (mainly because I encountered a lot of wrong or not complete information given by many "tutorials" out there). The version that did work is the one absolutely copy/pasted from Facebook guide to PHP SDK. Supposing there's an already configured Javascript SDK, I opened my index.php page and started with SDK inclusion:
//autoload is needed to include all sdk classes (not needed using Composer)
require_once ('./inc-fb-sdk/autoload.php');
Then, I had to explicitly tell the SDK to load some of the included classes; this is needed to make use of those classes:
use Facebook\FacebookJavaScriptLoginHelper;
use Facebook\FacebookRedirectLoginHelper;
use Facebook\FacebookRequest;
use Facebook\FacebookResponse;
use Facebook\FacebookSDKException;
use Facebook\FacebookSession;
use Facebook\FacebookRequestException;
use Facebook\GraphObject;
use Facebook\GraphUser;
And, of course, we initialize PHP SDK creating the object (use your AppID and AppSecret in the following line):
FacebookSession::setDefaultApplication('App_id', 'App_secret');
Finally, this is the code from the Guide, with some added comments and echoes, to show if user is logged in or not:
//create object that is used to check login
$helper = new FacebookRedirectLoginHelper();
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(\Exception $ex) {
// When validation fails or other local issues
}
//show if the user is logged in or not
if ($session) {
// Logged in
echo ('User is logged in');
} else {
echo ('User is not logged in');
}
Since you're already using the Login API, you only have to test loggin in/out from facebook and then refresh the page, to see the various situations that could happen.
And this should answer the two questions at the end of your post.
Hope this helps.
Note from #parse
You need to pass redirectUrl when you try to call FacebookRedirectLoginHelper(redirectUrl), otherwise you will get 'Missing argument' warning followed by this notice 'Undefined variable: redirectUrl in FacebookRedirectLoginHelper.php on line 77'

How to clear the data of Facebook App object

I have visited this link but cant get any help
$facebook->getUser() ALWAYS Returning ID - Can't Logout
the problem is when $facebook->getLogoutUrl is executed it just logout the user from facebook means destroy the facebook session but data return by the app is still there on the page. how to clear that data.
what i want is when logout link is clicked than the data on my app page also clear and login with facebook link appears.
here is the link to my example page
http://www.webdesigncc.info/demoz/myfacebook/examples/example.php
This may solve your problem
function facebook_logout()
{
$logout = $facebook->getLogoutUrl(array('next'=>'your url to be redirected after logout'));
$facebook->destroySession(); /*To destroy facebook sessions.
Available in facebook php sdk*/
$session_destroy(); //Optional if you want to destroy your site's sessions
header("Location:$logout");
}
Using the following way you can clear all datas.
public function destroySession() {
$this->setAccessToken(null);
$this->user = 0;
$this->clearAllPersistentData();
}

$facebook -> getUser() returns wrong value?

The question is the same as title. I'm using the latest php-sdk (v3.1.1) to operate server-side authentication flow.
I have 2 tabs in Chrome, one is my Facebook page and the other is php test page. These 2 problems happen many times:
$facebook->getUser() still returns 0 even when I logged in.
$facebook->getUser() still returns an ID even when I logged out.
I have to do a work-around of this: try initiating a graph API request with provided access_token, and check if $response->error->type == "OAuthException" to ensure there's an active session or not.
Is there any way to use $facebook->getUser() "stably"? I've searched a lot through SO but not found best answer for php-sdk 3.1.1 yet.
Highly appreciate any helps. Thanks.
Login.
As per documentation example of FB SDK, getUser() returns userId even when you're logged out, but have cookies associated with FB account.
To detect is user logged in you should use
$user = $facebook->getUser();
//Check Access token
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
if ($user) {
//logged-in
} else {
//not logged-in
}
To login in your app make user logs in in your app, not on neighbouring tab, by following this url (make sure that you're passing the scope based on intended actions performed by your app):
$loginUrl = $facebook->getLoginUrl(
'scope' => ...
);
Logout. Seems that your PHP server is storing some values of access tokens per session, so even when you're logged out in your browser, your server still have these tokens valid. Actually, I don't know, is it bug or feature, but they're not destroyed by Facebook after user logout.
To destroy these tokens I'm using these:
$facebook->destroySession();
I'm calling it every time when user logs-out by $facebook->getLogoutUrl();

facebook connect api static url

Is there a way to use the facebook connect api in a static way?
When we use the facebook php sdk the link or button to login to facebook is something like https://www.facebook.com/dialog/oauth..................
what I want is to eliminate the include of the php sdk on every page, because it will cause some extra processing and server load in peak times.
I want to make a session check to know if the user is logged in, by checking for exemple if his facebook user id and name are stored in the session, then if not, display a static login button. then after login with facebook he gets to facebook-login.php which will include the facebook php sdk and process his data and store them in the session, so that he remains logged without including the php sdk in each page.
the url structure that I get with $facebook->getLoginUrl() is:
https://www.facebook.com/dialog/oauth?client_id={MY_APP_KEY}&scope={PERMISSIONS}&redirect_uri={MY_SITE/facebook-login.php}&state={A_32_CHAR_CODE_LIKE_MD5_MAYBE}
The final question is: WHAT WOULD BE THE URL IN THE LOGIN BUTTON?
just load the sdk and do something like:
echo 'Connect to Facebook';
that url will always be valid for a logged out user
This is a good question. First, a user is logged into you app means that you have a valid access token for the user.
And there is no way to be sure that an access token is valid before making an API call with this access token. So if you want to make sure the user is still logged in on each page, you have to make an API call to Facebook on each of them. Kind of heavy, but there is no other solution.
What you can do is assume that the access token you have is valid and check only once a while (when you really need to be sure the user is logged in).
You can have different scenario :
you have no Facebook data about the user : the user is not logged in your app for sure.
you can read the user ID, but you may not have an access token for this user : the user may not be logged in.
you can read an access token, but it may not be valid (has expires or revoked by the user) : the user may not be logged in.
you have a valid access token : the user is logged in for sure.
You can read the user ID and the access token in the session. The session array looks like that :
[fb_148195765253871_access_token] => 14819576525...
[fb_148195765253871_user_id] => 1536397056
The number in the keys of the array (here 148195765253871) is your app ID.
So what you can do on each page is to check if those keys are set and if they are not, load the SDK and double-check (because the access can be store in some other places that the SDK is reading) :
if (isset($_SESSION['fb' . YOUR_APP_ID . 'access_token'])) {
// assume to user is logged in
// and keep going
} else {
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
// Make an API call to be sure the user is logged in
// ie : that you have a valid access token
$user = $facebook->getUser(); // User ID
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
if ($user) {
// The user is logged in for sure
} else {
// The user is not logged in for sure
// Make him log in
echo 'Login with Facebook';
}
}
Hope that helps !
The selected answer does not really answer the question.
If you would like to isolate all the Facebook code necessary for generating the getLoginUrl function call into a separate file you can do this easily by using meta refresh.
So in your header point the link "Login With Facebook" to "facebook_login.php". On this page include the necessary calls from the SDK for getLoginUrl and than add the following line of HTML.
<meta http-equiv="refresh" content="0;URL=<?=$helper->getLoginUrl(array('email', 'user_friends'));?>">
I tested this out multiple times and it works.
FYI using Facebook SDK 4.0.

Facebook API - Session still exists after user logout

I am using Facebook php-sdk in my iframe facebook app to get user login status.
Right after I sign out using facebook Account > Log out link, the session is not destroyed yet. I must wait a few minutes before old session expires, then my app will again get the correct login status.
I expect the facebook to kill itself and the session when user signs out. How do I manually kill the session?
Here is my code:
$initParams = array(
'appId' => $conf['app_id'],
'secret' => $conf['secret_api_key'],
'cookie' => TRUE,
);
$fb = new Facebook($initParams);
$fb->getSession(); // will return a session object eventhough user signed out!
SOLVED:
calling $fb->api('/me') will destroy the session if user has previously logged out.
I've changed my code as following:
if ($session)
{
try
{
$fbuid = $fb->getUser();
$me = $fb->api('/me');
}
catch(FacebookApiException $e){}
}
If the API call is unsuccessful, $session will be set to NULL. Very weird behavior, I don't explain everything that is going on here but it solved my problem of having residual session object not being updated via getSession() method.
I'm using $fb->getUser() and what I did was almost identical with yours.
if ($fb->getUser())
{
try
{
$me = $fb->api('/me');
}
catch(FacebookApiException $e){
**$fb->destroySession();**
}
}
I found that using only API to check whether FB is logged out or not sometimes is inconsistent, but with destroySession(), the session will surely be destroyed.
if you are using the javascript FB.INIT calls on the login page, then set status to false from true.
details about the status attribute :
http://developers.facebook.com/docs/reference/javascript/FB.init/
Try finding the formatData function somewhere at LoginWindow (AS3) and find this line:
vars.redirect_uri = FacebookURLDefaults.LOGIN_SUCCESS_URL
Change the value for http://www.facebook.com/ and logout from that html page when logged in.
This is a temporary solution to logout if you are developer, not the end user.
Facebook should disassociate the session from the account that the session belonged to. You can use Facebook::getUser() to check whether this was done:
if ($fb->getUser() === null) {
// User logged out
} else {
// User logged in
}
Try $facebook->setSession(null) or using javascript Logout
Logout does not work any way you do.
Try posting this link in your browser, after you log in to facebook.
https://www.facebook.com/logout.php
What happen? it takes you to your facebook. No logout at all.
What ever you do, check the function (depends on your API) handleLogout and check the output. In my case, it returns the entire facebook html page.
The only way I've managed to solve this problem was by clearing the session using the signed request to check the user id:
$facebook = Membership::getFacebookApp();
$signed_request = $facebook->getSignedRequest();
if(isset($_SESSION['facebook_id']) && $signed_request['user_id'] != (int)$_SESSION['facebook_id']){
$_SESSION = array();
}

Categories