Requesting facebook permissions on tab page in PHP - php

I am having one facebook pagetab application and I am stuck in following situation
I need to check if user login or not
if not then redirect to login url with user_likes,publish_actions,email permissions
and also user has liked page or not.
if not liked then show the like gate
Now in above I am stuck following error which I am getting in FB pagetab (iFRAM)
Refused to display 'https://www.facebook.com/v2.0/dialog/oauth?client_id=839424369402407&redire…c8682d9a9fb5b&sdk=php-sdk-4.0.9&scope=email%2Cuser_likes%2Cpublish_actions' in a frame because it set 'X-Frame-Options' to 'DENY'.
Now I am think to implement the flow with JS sdk, get the access token and then pass it to php code using ajax call
Is there any better way to solve this situation??
here is the code
try {
$session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
error_log($ex->getCode());
error_log($ex->getMessage());
} catch(\Exception $ex) {
error_log($ex->getCode());
error_log($ex->getMessage());
}
if($_GET['error']=="access_denied"){
header("location:/login/");
exit;
}else if (isset($session) || (isset($_SESSION['fb_user_session_access_token'])) && !empty($_SESSION['fb_user_session_access_token'])) {
if(isset($session))
$_SESSION['fb_user_session_access_token'] = $session->getToken();
else{
$access_token = $_SESSION['fb_user_session_access_token'];
$session = new FacebookSession($access_token);
}
try {
$user_profile = (new FacebookRequest(
$session, 'GET', '/me'
))->execute()->getGraphObject(GraphUser::className());
$email = $user_profile->getProperty('email');
$name = $user_profile->getProperty('name');
$fb_id = $user_profile->getProperty('id');
$query = mysql_query("select id, email from ntuc_users where email = '$email'");
$user_found = mysql_num_rows($query);
if(!$user_found){
//code deleted
exit;
} catch(FacebookRequestException $e) {
error_log($e->getCode());
error_log($e->getMessage());
//if token get expired
$loginUrl = $helper->getLoginUrl(array('req_perms' => 'email'));
header("location:".$loginUrl);
exit;
}
}
else
{
$loginUrl = $helper->getLoginUrl(array('req_perms' => 'email'));
header("location:".$loginUrl);
exit;
}
thanks in advanced

After 2 days research, I got this.. here is the flow which I have implemented for my app
#BjörnKaiser mentioned Facebook policy doesn't support LIKEGATE anymore.. and its true ..
So I have go through FB policy and got the following ans
Only incentivize a person to log into your app, like your app’s Page, enter a promotion on your app’s Page, or check-in at a place. Don’t incentivize other actions. Effective November 5th, 2014, you may no longer incentivize people to like your app's Page
FB POLICY
However as ref. to above information, i tried to implement likegate flow but FB hardluck with FB APP review team
But I got one more ref. from the review team
Please note that using "user_likes" to check if someone has liked your Facebook use case is not approvable. User_likes provides information to all of a person's likes, and the entirety of this data should be used to enhance the app experience. If you need to determine who has already liked your page, please use signed requests for Page Tab apps.
FB USER LIKE POLICY
Using signed requests, at least for pagetab it works like a charm :).. but for mobile website, I have removed the it
Here is the code:
if( isset($_REQUEST['signed_request']) )
{
$user_data = $this->parse_signed_request($_REQUEST['signed_request']);
$access_token = $_SESSION['fb_user_session_access_token'];
}
if( (isset($user_data['page']["liked"]) && !empty($user_data['page']["liked"]) && $user_data['page']["liked"]) || $this->deviceType != "computer")//no like gate for mobile
{
//my code ...
}
private function parse_signed_request($signed_request) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$secret = FB_APP_SECRET; // Use your app secret here
// decode the data
$sig = $this->base64_url_decode($encoded_sig);
$data = json_decode($this->base64_url_decode($payload), true);
// confirm the signature
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
$this->log->write('Bad Signed JSON signature!');
return null;
}
return $data;
}
private function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
I hope it helps someone else...

Related

Same facebook problems ... OAuthException: An active access token must be used to query information about the current user

So this is working fine... But when I refresh the page twice(or click on two pages who include this script fast) it gives this error
OAuthException: An active access token must be used to query information about the current user.
Any ideas?
<?php
$app_id = '***************';
$app_secret = '**************';
$app_namespace = '****************';
$app_url = 'http://apps.facebook.com/' . $app_namespace . '/';
$scope = 'email,publish_actions';
// Init the Facebook SDK
$facebook = new Facebook(array(
'appId' => $app_id,
'secret' => $app_secret,
));
// Get the current user
$user = $facebook->getUser();
// If the user has not installed the app, redirect them to the Login Dialog
if (!$user) {
$loginUrl = $facebook->getLoginUrl(array(
'scope' => $scope,
'redirect_uri' => $app_url,
));
print('<script> top.location.href=\'' . $loginUrl . '\'</script>');
}
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me', 'POST');
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
//<img src="https://graph.facebook.com/?php echo $user; ?/picture">
//?php print_r($user_profile); ?
?>
I personally find it easier to manage the access_token myself. Facebook's Graph API secures protected endpoints by requiring that an access_token be passed in. The PHP SDK abstracts this away, but I have never been comfortable with Facebook handling the information because sometimes it just doesn't work. This isn't to say that the library is bad, but only that I haven't been using it correctly. Keep this caveat in mind.
It looks like you're working with a Facebook Canvas App. When the user successfully authenticates for the first time, Facebook will send an access_token in $_GET. At this point, you should save this to your database, since that access token is good for 3 months or so.
At the point, from then on, you can pass in the access_token in the call parameters:
try {
$user_profile = $facebook->api('/me', 'POST', array(
"access_token" => '' // access token goes here
));
} catch (FacebookApiException $e) {
// error handling
}
Given that Facebook is returning the error that you need an access token in order to call the /me resource, it looks like $facebook->getUser(); is returning something. You may want to double-check what it is.
While I'm here, you're using this logic:
if (!conditional) {
// do something
}
if (conditional) {
// do something else
}
Confusing. Use else:
if (conditional) {
// do something
} else {
// do something else
}

Determine if a user has liked my page using Facebook PHP SDK?

My search has come up empty because when you search for "Facebook" and "like" I get all kinds of other results.
I have an app that is only on my company's Facebook page. In that app I need to find out if the user has liked the company's page. I'll show one thing if not and another thing if so. How can I do this using the Facebook PHP SDK v.3.1.1?
It can be done this way:
<?php
require('facebook.php');
$config = array(
'appId' => 'your facebook app id',
'secret' => 'your facebook app secret code',
'allowSignedRequest' => false
);
$facebook = new Facebook($config);
$user_id = $facebook->getUser();
if (isset($user_id)) {
try {
$likes = $facebook->api('/me/likes/your_facebook_page_id_here', 'GET');
if (!empty($likes['data'])) // if user has liked the page then $likes['data'] wont be empty otherwise it will be empty
{
echo 'Thank you for liking our fan page!';
}
else {
//show something else
}
} catch (FacebookApiException $e) {
$login_url = $facebook->getLoginUrl();
echo 'Please click here to login into your Facebook account.';
error_log($e->getType());
error_log($e->getMessage());
}
} else {
$login_url = $facebook->getLoginUrl();
echo 'Please lick here to login into your Facebook account';
}
?>
The user will click on the "Please click here to login into your Facebook account." text which will redirect it to Facebook app permissions page, once user allows the permission to your app the code will fetch user's data and will display what ever you want if user hasn't liked your fan page.
You can do this using FQL. You'll also need to make sure that you have the user_likes permission set.
I pulled this example from an older app that is now offline, it may need to be changed depending on what Facebook has changed in their last round of updates. Lately I've been using javascript and I subscribe to the edge.create event.... just replace the page_id with your page's id and give it a try
$checkIfUserLikePage = $facebook->api(array(
"method" => "fql.query",
"query" => "select uid from page_fan where uid=me() and page_id=1234567"
));
$checkIfUserLikePage = sizeof($checkIfUserLikePage) == 1 ? true : false;
This should work for you! I had to do a lot of these types of pages so I created a really simple way of creating like gated pages. https://github.com/DrewDahlman/FBVersion
Enjoy!
$signed_request = $_REQUEST['signed_request'];
function parsePageSignedRequest() {
if (isset($_REQUEST['signed_request'])) {
$encoded_sig = null;
$payload = null;
list($encoded_sig, $payload) = explode('.', $_REQUEST['signed_request'], 2);
$sig = base64_decode(strtr($encoded_sig, '-_', '+/'));
$data = json_decode(base64_decode(strtr($payload, '-_', '+/'), true));
return $data;
}
return false;
}
if($signed_request = parsePageSignedRequest()) {
if($signed_request->page->liked) {
$this->assign('verify', $signed_request->page->liked);
}
else {
echo "Please click on the Like button to view our Coupons!";
jexit();
}
}
I hope this will help you :)
Old topic, but wanted to weigh in as I have recently learned a lot about how to do this and have had to put it into practice.
Have a look at this link: http://nickring.com/blog/2012/11/facebook-fan-gate-using-php/. It uses the signed_request variable as some of the other responses show, but it shows how it does not require requesting the signed_request variable via $_REQUEST.
The one main thing to remember is that signed_request is only available when the PHP script accessing signed_request is run within Facebook. If you run this script outside of Facebook in a script attempting to use the Facebook API, it will return an empty array.
Here's an example - the following script will run when you go to this address: https://www.facebook.com/yourFacebookPage/app_xxxxxxxxxxxxxxx with 'xxxxxxxxxxxxxxx' being the app ID.
// Check if the user has liked us on Facebook, require the Facebook SDK
require_once('linked/facebook/facebook.php');
// Setup the Config
$config = array(
'appId' => 'xxxxxxxxxxxxxxxxx',
'secret' => 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
'cookie' => true
);
// Create a Facebook SDK instance
$facebook = new Facebook($config);
// Get the signed_request variable that we so desparately need
$signed_request = $facebook->getSignedRequest();
$like_status = $signed_request["page"]["liked"];
// Make sure that it worked
if (!empty($signed_request))
{
// Get the signed_request information
if ($like_status == 1)
{
// Wo0t! Show the FB fan only page stuff here
}
else
{
// Show the 'Please like us page'
$page = file_get_contents('pages/facebookLikeUs.html');
// Finish the page
echo $page;
exit();
} // End if ($like_status == 1) ELSE Clause and IF
} // End if (!empty($signed_request)) IF Clause
else
{
// Damn, it didn't work. Show an error
}
The above script is the script that is called from the URL set in the Canvas URL in the "App on Facebook" section of the App's settings. The facebookLikeUs.html page is simply a page asking them to click "Like" to continue. If I'm in a situation that I want them to be redirected back into a website that requires the Facebook like I simply replace the // Wo0t! section with something like this:
// Wo0t! They're all set, establish some cookies, get a cookie, and redirect back to the PHD program site
setcookie('fbls', $signed_request['page']['id'] . '-' . $signed_request['user_id'], time() + 300);
$redirectURL = "http://www.myurl.com/theScriptIWantToReceiveTheUserFromFB.php";
// Since Facebook really wants to keep us in the page, we need to create a page that will automatically break out of FB
$page = file_get_contents('pages/facebookRedirectBack.html');
// Replace some stuff
$page = str_replace('$redirectURL', $redirectURL, $page);
// Output the page
echo $page;
exit();
With the facebookRedirectBack.html page being this:
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
window.top.location.href = '$redirectURL';
</script>
</body>
</html>
If you're looking to have a bit more security on this, you can have the redirecting PHP script write some cookies and attach them to the URL such that the receiving script must compare the cookies and the URL params then delete the cookies after they've been read.
Hope this helps as I personally haven't found any consistent information on this subject.

Why is Facebook PHP SDK getUser always returning 0?

I'm trying to work with a website that requires some information from a Facebook user, I'm using PHP and JS SDKs.
I have a function in PHP:
public function isLoggedOnFacebook() {
$user = $this->_facebook->getUser();
if ($user) {
return $this->_facebook->api("/$user");
}
return false;
}
On a class that is holding the facebook object from the SDK in $this->_facebook.
Then on a block I do this:
<?php if (!$this->isLoggedOnFacebook()): ?>
<div>
<fb:login-button show-faces="true" perms="email" width="500" />
</div>
<?php endif ?>
And the FB JS environment is properly set up (I think) so it works. So the user gets the pop up and authorizes the site.
The problem is even after the app is been authorized by the user $user is always 0, meaning $facebook->getUser() always returns 0, and then lists the faces of users, including the logged user, but if I make it call $facebook->api('/me') or whatever, then it'll throw the invalid token exception.
I've seen this problem, but I haven't seen a solution, I have no idea
where the problem is and I run out of ideas.
There's a Website tab on the developers' Facebook page in the apps section, where you can set up your Site URL and your Site Domain, and I'm thinking this are the cause of my problem, but I have no knowledge of exactly what these fields are supposed to contain.
I had the same problem and I figured it out that is because SDK uses the variable $_REQUEST and in my environment is not true that is merged with $_GET, $_POST and $_COOKIE variables.
I think it depends on the PHP version and that is why someone made it work by enabling cookies.
I found this code in base_facebook.php:
protected function getCode() {
if (isset($_REQUEST['code'])) {
if ($this->state !== null &&
isset($_REQUEST['state']) &&
$this->state === $_REQUEST['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $_REQUEST['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
And I modified it as you can see below by creating $server_info variable.
protected function getCode() {
$server_info = array_merge($_GET, $_POST, $_COOKIE);
if (isset($server_info['code'])) {
if ($this->state !== null &&
isset($server_info['state']) &&
$this->state === $server_info['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $server_info['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
I ran into similar problem. $facebook->getUser() was returning 0 and sometimes it returned valid user id when user wasn't actually logged in, resulting in Fatal Oauth error when I tried to make graph api calls. I finally solved this problem. I don't know if it is the right way but it works. Here is the code :
<?php
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 <> '0' && $user <> '') { /*if valid user id i.e. neither 0 nor blank nor null*/
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) { /*sometimes it shows user id even if user in not logged in and it results in Oauth exception. In this case we will set it back to 0.*/
error_log($e);
$user = '0';
}
}
if ($user <> '0' && $user <> '') { /*So now we will have a valid user id with a valid oauth access token and so the code will work fine.*/
echo "UserId : " . $user;
$params = array( 'next' => 'http://www.anujkumar.com' );
echo "<p><a href='". $facebook->getLogoutUrl($params) . "'>Logout</a>";
$user_profile = $facebook->api('/me');
echo "<p>Name : " . $user_profile['name'];
echo "<p>";
print_r($user_profile);
} else {/*If user id isn't present just redirect it to login url*/
header("Location:{$facebook->getLoginUrl(array('req_perms' => 'email,offline_access'))}");
}
?>
Check out this blog post: http://thinkdiff.net/facebook/new-javascript-sdk-oauth-2-0-based-fbconnect-tutorial/
New JS SDK has been released - https://developers.facebook.com/blog/post/525
You need to ensure that your app is set to pick up the code parameter from the Query String rather than the uri_fragment, this can be set on facebook apps page apps>settings>permissions.
That did it for me using $facebook->getLoginUrl() to provide the login URL.
Check your config array.
Ensure that you are using proper string encaps quotes when setting the values.
$config = array();
$config["appId"] = $APP_ID;
$config["secret"] = $APP_SECRET;
$config["fileUpload"] = false; // optional
This works.
$config = array();
$config[‘appId’] = 'YOUR_APP_ID';
$config[‘secret’] = 'YOUR_APP_SECRET';
$config[‘fileUpload’] = false; // optional
This is a direct copy/paste from the website http://developers.facebook.com/docs/reference/php/ and does NOT work because of the odd squiggly quotes.
the long answer is that your hash for your "checking" of the app signature is not coming out to a correct check, because the app secret is not returning a valid value (it's returning nothing, actually)... so the hash_hmac function is returning an incorrect value that doesn't match properly, etc...
After debugging through the base_facebook.php I found, because somehow I had lost my .crt file the access token is forever invalid. Make sure you have your fb_ca_chain_bundle.crt available at: https://github.com/facebook/facebook-php-sdk/blob/master/src/fb_ca_chain_bundle.crt
Hours and hours down the drain. None of the posts about this on Stack Overflow or other sites provided the solution to my problem. I finally went in to the library code and figured out exactly where it was dying.
On my development machine, which uses XAMPP for Windows, I kept getting the 0 for logging in, while my test server would work properly. After realizing an exception was being thrown but hidden, I put an $e->getMessage() in base_facebook.php, which pointed out I was having an SSL error. The following post, HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK, led me to a solution.
The solution:
In base_facebook.php, add the following before curl_exec($ch):
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
You should probably wrap the above in whatever flags you use to determine if you are in development mode, because you won't want the above line in a production system. For instance:
if ( getenv( 'environment' ) === 'development' ) {
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
}
I checked and test a long time, Now I found the reason.
Please login developer apps, in settings-->Advance-->Migrations-->Deprecate offline access-->disabled.
You will find $facebook->getUser() will work.
another thing. had better add domain when new the facebook class;
$facebook = new Facebook(array(
'appId' => APP_ID,//$app_id,
'secret' => APP_SECRET,//$app_secret,
'cookie' => true,
'domain'=>'xxxdomain.com',
));
$session = $facebook->getUser();
Try this in your piece of code:
on if condition true you'll be reirected to facebook then login yourself and i hope you'll good to go by then but remember use new libraries of php SDK
if(($facebook->getUser())==0)
{
header("Location:{$facebook->getLoginUrl(array('scope' => 'photo_upload,user_status,publish_stream,user_photos,manage_pages'))}");
exit;
}
else {
$accounts_list = $facebook->api('/me/accounts');
echo "i am connected";
}
i solved this as i faced the same problem.
Just goto developers.facebook.com/apps then navigate to your app
hit EDIT APP button
IF you have check "App on facebook" and have entered a canvas url to it
the app will not work out side the facebook
will work under apps.facebook.com/
just remove this check it worked for me
<?php
require 'facebook.php';
// Create our application instance
// (replace this with your appId and secret).
$facebook = new Facebook(array(
'appId' => 'YOUR_APP_ID',
'secret' => 'YOUR_APP_SECRET',
));
// 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();
}
// This call will always work since we are fetching public data.
$naitik = $facebook->api('/naitik');
?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<title>php-sdk</title>
<style>
body {
font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
}
h1 a {
text-decoration: none;
color: #3b5998;
}
h1 a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<h1>php-sdk</h1>
<?php if ($user): ?>
Logout
<?php else: ?>
<div>
Login using OAuth 2.0 handled by the PHP SDK:
Login with Facebook
</div>
<?php endif ?>
<h3>PHP Session</h3>
<pre><?php print_r($_SESSION); ?></pre>
<?php if ($user): ?>
<h3>You</h3>
<img src="https://graph.facebook.com/<?php echo $user; ?>/picture">
<h3>Your User Object (/me)</h3>
<pre><?php print_r($user_profile); ?></pre>
<?php else: ?>
<strong><em>You are not Connected.</em></strong>
<?php endif ?>
<h3>Public profile of Naitik</h3>
<img src="https://graph.facebook.com/naitik/picture">
<?php echo $naitik['name']; ?>
</body>
</html>
$facebook->getUser() will return 0, if the user doesn't authenticate the app.
use $facebook->getLoginUrl to get the URL to authenticate the app.
I was having the exact same problem on my Facebook app, and I finally figured it out after 2 days of hair pulling frustration. It turned out to be an issue with the redirect-uri in the getLoginUrl()! if it doesn't match the registered app domain through facebook, they return the error, and the user gets returned as 0 (the default user value).
I had same problem with getUser(), It returns 0 in IE 8. I found a solution after doing some research. Follow the link below. This worked like a charm.
http://www.andugo.com/facebook-php-sdk-getuser-return-0-value-on-ie/
After some desperate hours, here is what caused the same issue on my server: If you use SSL, make sure that port 443 is not blocked! I opened the port last year, but it appeared that my webhoster somehow did a reset recently.
If you use the new SDK 3.1.1 and JS you need to add new variable to FB.init routine called
oauth : true
to use the new OATH 2.0 Protocol !
Then update your login button while perms are not allowed please use scope instead of perms
getUser() and PHP-SDK silently fails if _REQUEST like globals dropping by http server by misconfiguration. I was using wrong-configured nginx and after tracing code ~3 hours solved this problem via vhost configuration change.
I wrote a comment about solution here: https://github.com/facebook/php-sdk/issues/418#issuecomment-2193699
I hope helps.
A facebook->getUser() will return 0 when there is no logged-in user. (https://developers.facebook.com/docs/reference/php/facebook-getUser/)
To resolve this, the Facebook JS SDK provides an access token from a successful login which you can use with the Facebook PHP SDK.
The javascript below will check whether or not a Facebook login already exists and your Facebook App is authorized:
FB.getLoginStatus(function($response) {
if ($response.status === 'connected') {
var uid = $response.authResponse.userID;
var accessToken = $response.authResponse.accessToken;
_accessServer(uid, accessToken);
} else if ($response.status === 'not_authorized') {
_loginPopup();
} else {
_loginPopup();
}
});
The function _accessServer opens another request back to your server, sending the access token.
The function _loginPopup should open the Facebook login popup requesting the appropriate permissions for the user to "allow access" to your application.
The PHP application should then pass the access token back to the Facebook API:
$facebook->setAccessToken($new_access_token);
$uid = $facebook->getUser();
https://developers.facebook.com/docs/reference/php/facebook-setAccessToken/
Hope that helps.
Adding this line solved this problem for me in IE9:
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"'); // This is the main cause to use on IE.
If this question is still relevant to people, I'd like to contribute my 2 cents as I struggled quite some time to get things working.
First of all, try out the SDK that would suit you, whether it be PHP or JS. In essence they both do the same stuff, it's just that JS might handle it a bit more elegant (with the pop-up dialog and what not). There's a lot of different tutorials, manuals and examples out there! It took me like a week to find 1 that suited me and that I could actually use. Once you've found the piece of code that works with the SDK you plan on using, it's time for you to alter the code to your specific needs.
Once I had finished my code, I started testing it. I noticed I was running my code on localhost, and I too was getting no result from my arrays. To answer your question: upload your code to a (sub)domain and try again. My code worked all the time, but because I did not have it online, it didn't work. If you already got it online, then my answer is not of use to you.
I'm sorry if this kind of small story isn't really meant to be on SO, but it might help people.
Good luck!
if ($facebook->getUser()) {
$userProfile = $facebook->api('/me');
// do logic
} else {
$loginUrl = $facebook->getLoginUrl($params = array('scope' => SCOPE));
header('Location:' . $loginUrl);
}
that how i fixed my problem, now it is returning me the detail of user profile for further processing. (it was such a headache)
These are good suggestions but the thing that worked for me is on Facebook itself. After refactoring the code many times I realized it's a problem with the configurations on Facebook.
The following steps resolved my issue.
1.) Under Basic > App on Facebook... I deselected that although you can leave it if you want
2.) Under Permissions > Privacy -> set to Public
Permissions > Auth Token -> set to Query String
3.) Under Advanced -> Authentication > App Type -> Web
The third step is the one that really fixed it all, not completely sure why though, hope that helps
Make sure you call this Facebook API-function getUser before any output, because it uses Session variables and Cookies. Headers can not be sent/read correctly if you did.
I also spent many hours looking at this and also found a solution. Might not be for you but it seems there is some issue with $_SERVER['QUERY_STRING'] so you need to set it into the $_REQUEST array.
I was using codeigniter and found that the following code above the library load worked.
parse_str($_SERVER['QUERY_STRING'],$_REQUEST);
parse_str($_SERVER['QUERY_STRING'],$_REQUEST);
$config = array();
$config["appId"] = "63xxxxx39";
$config["secret"] = "dexxxx3bf";
$this->load->library('facebook',$config);
$this->user = $user = $this->facebook->getUser();
if ($user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$user_profile = $this->facebook->api('/me');
//print_r($user_profile);exit;
} catch (FacebookApiException $e) {
echo '<pre>'.htmlspecialchars(print_r($e, true)).'</pre>';
$user = null;
}
$logout = $this->facebook->getLogoutUrl();
$this->fb_logout = $logout;
$this->fb_user = $user_profile;
} else {
$login = $this->facebook->getLoginUrl(array("scope"=>"email","redirect_uri"=>"http://domain/login/login_fbmember/"));
$this->fb_login = $login;
}
}
This issue is really weird. I have discovered that the problem was the static $CURL_OPTS array in the base_facebook.php.
Try to edit it from this:
/**
* Default options for curl.
*
* #var array
*/
public static $CURL_OPTS = array(
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_USERAGENT => 'facebook-php-3.2',
);
to
/**
* Default options for curl.
*
* #var array
*/
public static $CURL_OPTS = array(
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_USERAGENT => 'facebook-php-3.2',
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
);
The answer to my specific issue was that there were incompatibilities between the versions of the JS SDK and PHP SDK I was using and just upgrading them solved it.
The symptom of this issue is similar when it's caused by a variety of different things so you may do very well in scouting through the different answers available in this page.

Auth problems with OAuth (Facebook App), session is not available?

I want to read all birthdays of the friends from current user. I use the new Graph API of facebook. I request the authorization of the permissions (read_friendslist and friends_birthday) based on Facebooks insights example and php-sdk example. For reading the friendslist and the user details I used the Graph API with Facebook PHP SDK.
The upcoming code snippets are a short self contained correct example of my approach. If I try to use my app it requests login, then asks for permissions and then fails in printing all my friends due to the fact that no session is available. What's wrong here?
First is the birthday.php which is used by the following index.php, I removed some boilerplate code or code I think it's not causing this problem (identified by [...]). You can find the complete code on the end of this question.
<?php
function get_birthday_of_friends() {
$fbconfig['appid' ] = "MY_APP_ID";
$fbconfig['secret'] = "MY_APP_SECRET";
try{
include_once "facebook/src/facebook.php";
}
catch(Exception $o){
// [...] log error
}
// Create our Application instance.
$facebook = new Facebook(array(
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
'cookie' => true,
));
$session = $facebook->getSession();
$fbme = null;
// Session based graph API call.
if ($session) {
// [...] return birthdays
} else {
echo "No session found";
}
}
?>
The required lib.php is identically with the insights example.
<?php
// [...] Include and define app-id etc.
function get_access_token($base_url) {
if (isset($_REQUEST['access_token'])) {
return $_REQUEST['access_token'];
}
$params = array();
$params['client_id'] = APP_ID;
$params['redirect_uri'] = $base_url;
if (!isset($_REQUEST['code'])) {
$params['scope'] = 'read_friendlists, friends_birthday';
$url = FacebookMethods::getGraphApiUrl('oauth/authorize', $params);
throw new RedirectionException($url);
} else {
$params['client_secret'] = APP_SECRET;
$params['code'] = $_REQUEST['code'];
$url = FacebookMethods::getGraphApiUrl('oauth/access_token');
$response = FacebookMethods::fetchUrl($url, $params);
$response = strstr($response, 'access_token=');
$result = substr($response, 13);
$pos = strpos($result, '&');
if ($pos !== false) {
$result = substr($result, 0, $pos);
}
return $result;
}
}
// [...] Call get_access_token() and get_birthday_of_friends()!
?>
Can you help me with that? I added the whole source code on pastebin.com if this helps you to identify my problem. Source code on pastebin.com for "index.php" and "birthday.php".
Thank you in advance!
I am not sure if the method that you are using is deprecated or not, but I know it's the old way and you should try with the new one in order to get the auth token.
Take a look at this link:
http://developers.facebook.com/docs/authentication/signed_request/
In a glance, you have to:
Get the signed_request parameter from $_REQUEST.
Use the sample function provided in
the link to decode it Once you decode
it, you will have an array in which
there is a parameter called
oauth_token.
With this parameter, you can start
making calls to the Graph by
appending it to the URL e.g.
*https://graph.facebook.com/PROFILE_ID/pictures/?access_token=OAUTH_TOKEN*
Make sure that you have Oauth 2.0 for Canvas enabled into the Configuration settings of your app (Advanced tab).
I think in some browsers there's a prblem with third party cookies. Are you testing in Safari? And also, try to add permissions to the loginUrl - it's a bit more simple than adding and requesting the permissions with oauth.
If no session is available, I had to redirect to the login page and require the extended permissions with the parameters. This did the trick to me, thanks to manuelpedrera for helping me out.
$facebook->getLoginUrl(array('req_perms' => 'read_friendlists, [...]'));

Facebook PHP SDK - require login on specific account

I'm tired of digging through tons of tutorials/documentations which don't help me at all.
What I have now (everything is placed inside admin control panel):
If user is logged on correct account (administrator of page with granted rights), everything works fine, post on page is posted as impersonated site.
If he is logged on other account, nothing happens. Site redirects him to his wall.
If he isn't logged on any account, he's redirected to facebook login - if he logs onto correct account, he returns to acp (it's bad solution, because it'll clear his form)
I want to achieve:
If logged in, everything as it was
Else popup with login to specific (correct) account
At the moment I'm using only PHP, but solution with JS is permitted.
My code:
<?php
/*(...)*/
$facebook = new Facebook(array(
'appId' => $apiid,
'secret' => $secret,
'cookie' => true,
));
$session = $facebook->getSession();
$me = null;
if ($session) {
try {
$uid = $facebook->getUser();
$me = $facebook->api('/me');
} catch (FacebookApiException $e) {
error_log($e);
}
if($me) {
//In order to post to the page later on we need to generate an Access Token for that page, to do this we get me-accounts in the following api call
$accounts = $facebook->api('/me/accounts');
//Loop through the array off accounts to find the page with a matching ID to the one we need
foreach($accounts['data'] as $account){
if($account['id'] == PAGEID){
$ACCESS_TOKEN = $account['access_token'];
}
}
}
$message=$data['facebook_text'];
$attachment = array(
'message' => $data['facebook_text'],
'name' => $data['name'],
'description' => '',
'link'=>$someurl,
'access_token' => $ACCESS_TOKEN
);
if($image_url != NULL) $attachment['picture'] = $image_url;
try {
if($facebook->api('/PAGEID/feed', 'post', $attachment))
{
//other stuff
}
} catch (FacebookApiException $e) {
error_log($e);
//other stuff
}
}
else
{
$login_url = $facebook->getLoginUrl();
header("Location: $login_url");
exit;
}
/* (...) */
?>
Solution can't redirect anywhere, because it's inside form, so all data'll be lost.
I'm not really sure I understand what you want to do here, but this is what I use in a similar situation:
$session = $this->get_admin_session_of_page ($page_id);
$session = unserialize ($session);
$facebook->setSession ($session, false);
In the facebook php SDK there is a method to manually set the session, setSession. I save the page admin user session in DB with serialize, with the offline access and manage pages permission. Then when you need some admin privileges for the application you just unserialize it, and then use setSession. The second parameter is set to FALSE, so that this session is not saved in a cookie and logout the current user.
This way it's not important who is logged in, the work is always done as an admin of the page. I think this is safe to use in an automated script, for example to upload a user photo in a page album.
Of course, you must use caution with this if it gets more involved then that, or implement your own security.

Categories