Connect to a facebook app for longer than a session - php

I've been searching and trying around for a couple of hours, but I can't figure it out.
I use a facebook app to get some information of the user, therefor the user needs to connect to the app. The first time the user connects, he needs to give permission to the app on facebook. When the user comes back another day, he needs to click connect again, but the permission is already set.
I want the user to be connected longer than the session, so he doesn't need to click connect everytime he visits the site (in a new session). I've read a lot about offline_access etc but this is deprecated and probably not what I need at last. I've also read some solutions from 2 years ago, but they don't work anymore.
An example to summarize:
Assume the user visits my website and I know nothing about him. He gave permission to my app a few days ago. I want him to see Hello and the logoutlink without doing anything. I'm starting to wonder if this is even possible?
// Create our Application instance.
$facebook = new Facebook(
array(
'appId' => xxxxxxxxxx,
'secret' => xxxxxxxxxx,
)
);
// Get User ID
$fbuser = $facebook->getUser();
if($fbuser) {
$logoutUrl = $facebook->getLogoutUrl();
print 'Hello' . $logoutUrl;
} else {
$loginUrl = $facebook->getLoginUrl();
}
Thank you in advance!
Regards

I don't think that php is the way to go with this one...
You should use the facebook javascript sdk (https://developers.facebook.com/docs/reference/javascript/) with which you can log the user in..
If the user is already logged in to facebook and has a session (and of course has already authorized your application before) then you are all set, otherwise the user will have to login to facebook or authorize you application.
use the FB.getLoginStatus to check if the user is logged in, if he is not then present him with a button that will call the FB.login method

Yes you should only use facebook to get certain data then you should store all that data with the unique fb_user_id in your own database and create your own session for the user!
So during facebook signup social plugin you create a user in your own database, then during each login you actually create you own session and if you make it secure you can rely on your own session, if you use any facebook API stuff and your session is closed it will handle it on the facebook server, it might ask user to log in if they are logged out of facebook, but most people don't even logout so it just recreates the session!
so something like:
// Create our Application instance.
$facebook = new Facebook(
array(
'appId' => xxxxxxxxxx,
'secret' => xxxxxxxxxx,
)
);
inlcude "my_session_stuff.inc";
// Get User ID
if(!$user->user_exists){
$fbuser = $facebook->getUser();
}else{
$fbuser = $user;
}
if($fbuser) {
$logoutUrl = $facebook->getLogoutUrl();
$expires = (60*60*24*365);//expire in a year
$user = $myownSession->log_user_out($logoutUrl);
} else {
$loginUrl = $facebook->getLoginUrl();
$user = $myownSession->log_user_in($getLoginUrl,$expires);
}

Related

facebook login bug using fb php sdk

My problem is the following.
I have a website
http://de.gamercharts.com/
You can connect with facebook(if you don't have an account,an account will be created).
After this ,if you logout from the site ,you are logged out from facebook too.
Everything is ok so far.
The problem is that if I am logged out of the site (let's call the site GC) and logged out of facebook ,when I click "connect with facebook" on the site,I get logged in on the site,instead of being prompted to the facebook login screen.
When I print the user ,I see that even though I am logged out of facebook,I still have the user id.
Why does this happen,and how can I fix it ?
Thanx a lot to anyone who takes the time to answer.
For the record I am using Zend ,although I don't think it's relevant.
I did not implement the facebook login myself,I am continuing the work of someone else.
The problem is caused due to existence of Facebook Session Variables in your domain/site, even after logging out from facebook and your site. When someone logs out from your site, one should take care to destroy all the sessions[even facebook sessions]. For destroying facebook sessions in your domain/site, you can make use of the function destroySession(); [provided in the facebook php sdk] in your logout script.
$config = array();
$config['appId'] = 'YOUR_APP_ID';
$config['secret'] = 'YOUR_APP_SECRET';
$facebook = new Facebook($config);
$logout = $this->facebook->getLogoutUrl(array('next'=>'url to be redirected after logout'));
$facebook->destroySession(); // To destroy facebook Sessions
$session_destroy(); //To destroy sessions of your site
header("Location:$logout");
P.S Don't forget to include or call session_start() in the script
If you use facebook sdk, then you need use exception try-catch for checking if user is still logged in:
1$facebook = new Facebook(array(
2 'appId' => you id,
3 'secret' => you secret,
4));
5
6// See if there is a user from a cookie
7$user = $facebook->getUser();
8
9if ($user) {
10 try {
11 // Proceed knowing you have a logged in user who's authenticated.
12 $user_profile = $facebook->api('/me');
13 } catch (FacebookApiException $e) {
14 error_log($e);
15 $user = null;
16 }
17}
And after that you can get correct user id and other information from Facebook
Every time you need to request me-page. And if this page throw an error, then delete facebook user's data. User's id, and other facebook data stored in the cookies; when you logged out in the Facebook site, cookies for you site continue to be kept; your php-code will read this cookies:
1$user = $facebook->getUser();
and return user id.
With this code:
1$user_profile = $facebook->api('/me');
you check if this cookies is actuall, and if it isn't, you change it:
1$user = null;
All the matter in cookies

Facebook getLogoutUrl() doesn't work as expected

This is my code :
<?php
require_once("facebook-php-sdk/src/facebook.php");
define('YOUR_APP_ID', 'xxxxxxxxxxxxx');
define('YOUR_APP_SECRET', 'xxxxxxxxxxxxxxxxxxxxxxxx');
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$userId = $facebook->getUser();
if($userId){
$userInfo = $facebook->api('/' + $userId);
$fbid = $userInfo['id'];
$params = array();
echo '<img style="vertical-align:middle;" src="/img/fbicon.png">Logout</div>';
}
else{
$permission = array('scope' => 'email');
echo '<img style="vertical-align:middle;" src="/img/fbicon.png">Login with Facebook</div>';
}
?>
Login works perfectly, but when I click the Logout button it logs me out of facebook.com, but it stays logged on my website, which is exactly the opposite of what I want. I want the link to delete all facebook information from my website, but keep the user logged to facebook.
I don't know if I explained correctly what I need, but I'll clear things up if someone asks.
If you want the user to log out from your site but stay logged in to facebook then the answer is simple:
Don't use facebook->getlogouturl()
If after a successful login, you set a variable to be true, and use that to permit actions you only grant to a logged in user, then all your logout button will need to do is set that variable to false.
The issue here isn't the logout link (which is working properly, since it logs you out of Facebook), but it is how your website checks whether you are still logged into Facebook
The Facebook API you are using only deals with Facebook's side of things. The login link will log you into Facebook, and the logout link will log you out of Facebook. It doesn't affect your website directly.
You'll need to find out how your website decides whether you are still logged into Facebook or not, and go from there.

Post to Facebook Page Wall without logged in user

I have a Facebook app that I want to use to post on my customer's Facebook Page Walls on their behalf. I have it setup now so that when they authenticate my app I get the Access token, but when I go to post to the wall I am getting the following error: "OAuthException: Error validating access token: The session is invalid because the user logged out."
How can I post from my script without being logged in?
Here is my code:
include_once('fb-php-sdk/src/facebook.php');
$facebook = new Facebook(array(
'appId' => 'XXX',
'secret' => 'XXX',
));
try {
$page_id = '215133535279290'; //page id of the customer's facebook page
$args = array(
'access_token' => 'XXX', //access token received when user authenticated app
'message' => 'A test message'
);
$post_id = $facebook->api("/$page_id/feed","post",$args);
} catch (FacebookApiException $e) {
echo "Error:" . $e;
}
The new facebook API has what is called an extended access token (it replaces offline access: https://developers.facebook.com/roadmap/offline-access-removal/ I think) which I believe lasts upto 60 days (or something like that). To use it simply get the access token when the logs in through your website:
$token = $facebook->getAccessToken();
Save it to Db and use this token later:
$facebook = new Facebook();
$facebook->setAccessToken($accessTokenFromDB);
Then you should be able to continue as though the user is logged in.
As for the user being logged out part, make sure you are using the latest version of the API and not an old version and also make sure the stuff under the "Scenario 2: If you have been previously requesting offline_access - updated 4/30/2012" heading of the page I linked.
You could carry on using offline_access until 3rd of October, but then why if it's being turned off for real in 2 months time and would have to rewrite your code.
Get the publish_stream extended permission. Once you have this permission you can post feed stories using your app access token while the user is offline. There is no need for offline_access permissions or saving and using a user access token in this scenario.

Facebook PHP SDK - User not authenticated

I am using Facebook PHP SDK to authenticate the user. After generating the LoginUrl using the PHP SDK, the user clicking on that LoginUrl gets redirected to the Facebook page asking for permission. After clicking on the Go to App link, the user gets redirected back to my website http://www.mydomain.com/login/facebook_connect.
Problem: After being 'authenticated' by Facebook, the PHP script at http://www.mydomain.com/login/facebook_connect is unable to determine that the user has logged in via Facebook. At this point, $user = $facebook->getUser(); is 0.
Did I do something wrong? Thanks!
PHP Code for page that generates LoginUrl
require 'libs/fb-php-sdk/facebook.php';
// Create our Application instance
$facebook = new Facebook(array(
'appId' => '123',
'secret' => '123'
));
// Get User ID
$user = $facebook->getUser();
// Get Login URL
$loginUrl = $facebook->getLoginUrl(array(
"scope" => "email,user_education_history,user_work_history",
"redirect_uri" => "http://www.mydomain.com/login/facebook_connect/"
));
$data['fb_login_url'] = $loginUrl;
$this->load->view('splash', $data);
PHP Code for page user is redirected to after Facebook authentication
*http://www.mydomain.com/login/facebook_connect/*
require 'libs/fb-php-sdk/facebook.php';
$facebook = new Facebook(array(
'appId' => '123',
'secret' => '123',
));
// See if there is a user from a cookie
$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;
}
}
print_r($user_profile);
echo $user;
All seems correct.
Questions:
1.- I supposed that http://www.mydomain.com/ contains all your scripts, right?
2.- Are you using codeigniter? Or a codeigniter-based CMS? In that case maybe you have a session problem (very common in CI). Check it and we continue...
EDIT 2: In case of being a cookie related problem. Here is an image showing as you can use firebug with a cookie module to easily track your cookies:
So you can check how facebook cookies are being generated.
EDIT 3: Ok. So you are using CI and your FB cookies are being deleted. Maybe is a session problem. Here is a related answer where I explain how to use a session CI library replacement that generally solve all these kind of painful issues. Believe me, give it a try!
a.- Here it is: Codeigniter's Native session (there is a download link at the bottom)
b.- BUT, due that it is an old library you MUST made some hacks. You can check those simple hacks in the library's forum
c.- Just drop this file in codeigniter's library directory.
$facebook->getUser() uses a cookie to get the user. If you use CodeIgniter, or another library that "eats" cookies that PHP assigns automatically, you need to create a proxy page outside CI, that would pick up the cookie the redirect back into CI.
In other words, take to code you currently have in
http://www.mydomain.com/login/facebook_connect/
and create a copy in a regular PHP file:
http://www.mydomain.com/facebook_pickup.php
do not echo anything from the script (remove print_r), just redirect to
http://www.mydomain.com/login/facebook_connect/
and it would magically start working.

Can I store Facebook access token and use it later?

I am building a web app (PHP) that uses FB connect. I successfully register / sign in user with the help of the PHP lib provided by facebook. Also I can post to wall, using this code
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYPEER] = false;
Facebook::$CURL_OPTS[CURLOPT_SSL_VERIFYHOST] = 2;
$facebook = new Facebook(array(
'appId' => $fb_key,
'secret' => $fb_secret,
'cookie' => true, // enable optional cookie support
));
$session = $facebook->getSession();
if ($session)
{
$facebook->api('/me/feed', 'POST', array('message'=>$message, 'link'=>$link['href'], 'name'=>$link['text']));
}
However, if I manually go to my browser's cookie manager and delete the cookie that stores FB session, the code doesn't work. The only thing I have is user's FB ID which I store in DB. Is there any way to post to user's wall even if FB sessions is lost? Does it make sense to store user's FB access token in DB to post to wall later or is the access token relatively short-lived?
Here's an example situation that might happen in my app:
user clicks fb button, authorizes my app, gets redirected back to my site where I automatically create an account based on data provided by FB, also I store user's FB ID so that I could sign in this user later. Now he browses site, enters some info and this info gets posted to his wall. Everything is fine so far because user's browser holds the cookie created by FB. Now user leaves the site and contacts site admin. Admin opens his own browser, goes to admin interface and posts something on behalf of this user. Now, having that user's FB ID and assuming that user hasn't revoked permissions, can I still post this to his wall?
With the Facebook PHP SDK v3 (see on github), it is pretty simple to ask and use a user offline access token. Here is how you do that.
Get the offline access token
First you check if the user is logged in or not :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
If he is not, you generate the "Login with Facebook" URL asking for the offline_access permission :
if (!$user) {
$args['scope'] = 'offline_access';
$loginUrl = $facebook->getLoginUrl($args);
}
And then display the link in your template :
<?php if (!$user): ?>
Login with Facebook
<?php endif ?>
Then, when the user is logged in, you can retrieve the offline access token and store it. To get it, call :
if ($user) {
$token = $facebook->getAccessToken();
// store token
}
Use the offline access token
To use the offline access token when the user is not logged in :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$facebook->setAccessToken("...");
And now you can make API calls for this user :
$user_profile = $facebook->api('/me');
Hope that helps !
UPDATE: This answer is no longer valid as offline_access is deprecated.
You need to request the offline_access permission. Check the permissions doc.
EDIT Per the update and comments - some info on the removal of the offline_access can be found here.

Categories