OAuthException on Facebook Graph API Logout, Works After Refresh - php

I am using a modified version php-sdk version 3.0.0 sample code at github.com/facebook within the CodeIgniter framework as a helper.
My problem is just as the title says: When I click the logout anchor (provided by $Facebook->getLogoutUrl()) I am redirected back to the same page and receive an OAuthException:
Fatal error: Uncaught OAuthException: Error validating access token: The session is invalid because the user logged out. thrown in [...]/base_facebook.php on line 959
When I refresh, it loads the "login" anchor like it normally would. What is happening on that refresh/post-back that isn't happening on that initial redirect?
I realize this is limited information but due to the problem I think it may be a simple fix.
EDIT: This post seems to be relevant: http://forum.developers.facebook.net/viewtopic.php?id=71219
Specifically this line:
setcookie('fbs_'.$facebook->getAppId(), '', time()-100, '/', '.domain.com');
However, I am not sure how to implement this and still use $facebook->getLogoutUrl();.
Thanks in advance and just let me know if more information is necessary.

I was having the same problem and nearly pulling my hair out. However, after some research, it appears the problem is an offending cookie. This line on logout should fix it:
setcookie('fbs_'.$facebook->getAppId(), '', time()-100, '/', '.domain.com');
Ensure to add the '.' before the domain name if subdomains are being used.
I hope this helps!

As suggested, I tried:
setcookie('fbs_'.$facebook->getAppId(), '', time()-100, '/', '.domain.com');
This didn't work. What I did, was to just copy from the fb example code:
// Get User ID
$user = $facebook->getUser();
// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
// Login or logout url will be needed depending on current user state.
if ($user) {
$logoutUrl = $facebook->getLogoutUrl();
} else {
$loginUrl = $facebook->getLoginUrl();
}
The middle part, with if try get user_profile, is a test to get the user profile, and if it fails the userid will be unset. This will make the last part with getLoginUrl() and getLogoutUrl() correct.
I do believe setting the cookie is more correct, than to try a request and see if it fails... but since the setcookie didn't work, I didn't have a choice :(
Stupid facebook that returns a token with this $user = $facebook->getUser();, when the user actually is logged out.
Hope this helps those who is in need.

From the looks of your error it would appear your website is still trying to connect to Facebook using the SDK. When you run the logout function provided by Facebook make sure to clear whatever sessions or storage you have that triggers calls to Facebook.
It's likely that they aren't being cleared before you attempt your Facebook logout, and this is why it still thinks you have a connection but then works fine on refresh.

What I ended up doing was this:
$facebook->getLogoutUrl(array('next' => site_url('logout')));
Then in the 'logout' controller:
$_SESSION = array();
$this->load->view('myoriginalview');
On logout, the facebook logout url's query string redirect_uri value is set to redirect to the 'logout' controller which then clears the session and loads the view on which the logout button existed in the first place. Everything functions fine. Now I just have to figure out how to handle an expired session as opposed to a logged out user -_-
EDIT:
What I've done now is invalidate the cookie in the proper manner as described on the facebook developers forum. I really wish their documentation was better and described this for their PHP SDK.

Related

$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();

user is logged out from facebook, but website still gets his data

I've got following code:
$fb = new Facebook(array('appid'=>APPID, 'appsecret'=>APPSECRET));
$user = $fb->getUser();
if($user)
{
try {
$me = $fb->api('/me');
}
catch(FacebookApiException $e) {
error_log($e);
enter code here
$user = null;
}
if($user) { blah blah blah
And it works properly if user is not logged in and if the user logs in, it works. But only if he click link from $fb->getLogoutUrl() and successfully logs out from facebook, my app still holds his data. I read that trying $fb->api('/me') should throw an exception if user is logged out but it isn't. Clearing the $_SESSION table helps but I don't think that is properly solution.
Any idea's?
I think this might be caused by facebook's extended access token (I am not sure) which basically gives the same as offline access (in fact replaces it: https://developers.facebook.com/roadmap/offline-access-removal/ ) but for 60 days.
So I think it is nothing to really worry about. I am unsure what you mean by:
Clearing the $_SESSION table helps but i don't think that is properly
solution.
Since I am unsure exactly what you are "clearing", you might be clearing the accessToken in which case, yes that will stop you from accessing the users info, although be aware it DOES not deauth your app. Logging in and out are two completely different things to auth and deauth. The /me url will normally only throw an exception if your n ot allowed to access, i.e. user has deauthed your app.
I think using destroySession after logout ($fb->destroySession()) will solve most of your problems by destroying the cookies on your side and resetting the user access.

$facebook->getUser() returns a userid after logout

How do I check if the user is really loggedin? $facebook->getUser() still returns an ID after logout. Do I need to do something like $facebook->api('/me') just to check if the user is "really" logged in?
Well, FB PHP SDK in my opinion is quite tricky because it relies on a cookie sent from Facebook when you are logging into the Facebook. This cookie is not deleted whilst logging out. Because of that in below code the variable $uid could store a proper user facebook id:
$uid = $facebook->getUser();
So, as far as I know, call $facebook->api('/me'); will tell the truth whether the user is logged in or not.
try {
$facebook->api('/me');
/* user is really logged into FB */
} catch (Exception $e) {
/* user is not currently logged into the FB */
}
I use above code in my production application and it works well.
getLoginStatusUrl should do the trick.
I think that if you ask for offline_perms than you have access to user_id and so on. I don't know if you did, but most likely that should be the problem
Have you tried the method detailed in the Facebook PHP SDK Documentation?
$params = array(
'ok_session' => 'https://www.myapp.com/',
'no_user' => 'https://www.myapp.com/no_user',
'no_session' => 'https://www.myapp.com/no_session',
);
$next_url = $facebook->getLoginStatusUrl($params);
Returns a URL based on the user’s login status on Facebook. You can
get a different URL depending on whether the user is logged in, not
connected, or logged out of Facebook.

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();
}

Facebook Connect login failing after logout, something to do with cookies

I'm using the PHP SDK for facebook connect.
Now, I can log people in fine using this:
# active session
$session = $facebook->getSession();
if(!empty($session)) {
# Active session, try getting the user id (getUser()) and user info (api->('/me'))
try{
$uid = $facebook->getUser();
$user = $facebook->api('/me');
} catch (Exception $e){}
if(!empty($user)){
GET USER DETAILS FROM DATABASE, SET SESSIONS FOR MY SITE ETC
} else {
die("There was an error.");
}
However, when I log out of my site (which is just a simple logout script destroying the sessions) and then try to log in again using the same facebook script, it triggers the error, indicating that $user is empty. This happens if I stay logged into facebook or someone else tries it and carries on triggering the error until I clear cookies.
There must be something that I am supposed to clear when I log out or before someone logs in with facebook. But the documentation for Facebook is laughably bad and the forum is a complete shambles.
Note, I do not want to log the user out of facebook, only my site. But I obviously cant have the user have to clear their cookies whenever they want to log back in again.
Any help?
In case anyone is searching for this (as the facebook documentation and forum are so absolutely terrible) I just changed the setcookie value to false when you set up your secret key etc.
This means that the user would have to log in again if they left your site, but only if you are not setting your own session/cookie values. So it works perfectly for what I needed.

Categories