Following this discussion i can't figure it out how to getUserId from session or how to create session from a signed request in new SDK 4 for PHP? I'm trying to migrate my apps from old SDK to new one and my code doesn't work well.
I'm trying to get the user ID on page tab where i'm an admin. I've tried to getSession from FacebookPageTabHelper with no luck.
My php code:
session_start();
require_once '../api/facebook/autoload.php';
use Facebook\FacebookSession;
use Facebook\FacebookPageTabHelper;
FacebookSession::setDefaultApplication(APP_ID, APP_SECRET);
$pageHelper = new FacebookPageTabHelper();
$page = $pageHelper->getPageId();
$admin = $pageHelper->isAdmin();
$fan = $pageHelper->isLiked();
$appdata = $pageHelper->getSignedRequest()->payload['app_data'];
$session = $pageHelper->getSession();
$user = $session->getUserId(); // always empty
Facebook API doesn't provide you with this information anymore (if you use the user access token). You should get the ID of the user by looking at his posts or his comments, and even by this way you need to guess that he is a public user otherwise it will not work.
If you can login with the app token it should work but it's not easy to get confirmation for your application by Facebook.
Related
I am new in WordPress and PHP. I am using php-sdk of parse.com for developing my plugin. My php-sdk folder is inside my plugin folder. I have stored App ID , Rest API key and Master key in my database of WordPress.
For Parse initialization, I required App ID , Rest API key and Master key. I can fetch it from my WordPress database.
After parse initialization, I can fetch my data from parse. For fetching data you have to authenticate first. username and password are required to authentication. I am getting these username and password by a form. When I am submitting my form then I am initializing the parse and then authenticating it. I can fetch the data on same page as well. But I am going to other page then I can not get the data. I try to use following code on other page :
session_start();
require 'vendor/autoload.php';
use Parse\ParseUser;
$currentUser = ParseUser::getCurrentUser();
if ($currentUser) {
// do stuff with the user
echo "username: ". $currentUser->getObjectId();
} else {
// show the signup or login page
echo "Not Found";
}
I could not get my current user. How can I maintain the sessions in parse.com. I want to initialize and authenticate the users once for all. After that I can get the data from any of the page of my WordPress. How to solve this problem ? Can any body help me ??
After session_start() use:
\Parse\ParseClient::initialize(....);
\Parse\ParseClient::setStorage(new \Parse\ParseSessionStorage());
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'
First, I downloaded the Facebook PHP SDK and applied the first answer in here:
Using Facebook PHP-SDK 3.x to register/login user with Codeigniter 2.1.0
In my controller:
I try to get the user: $this->facebook->getUser(); .. If it's 0, I call another function $this->facebook_login(); - else I save some data in the database like name for example.
In facebook_login(), a Login Url is generated: $this->facebook->getLoginUrl() - and is passed to the view, which displays it.
So far I click on the login url and it redirects to Facebook, asks for approval and authentication and so on - then redirects me back to the page in "1".
The problem is, getUser is returning zero. I printed the $SESSION variable and found out that only fb{appId}_state is being set.
I tried creating another php file (login.php) that is not in the CI folder with the following code:
<?php
define('BASEPATH', '');
require_once('application/libraries/facebook.php');
$fb = new Facebook(array('appId'=>'...', 'secret'=>'...'));
$user = $fb->getUser();
if($user == 0){
$login = $fb->getLoginUrl();
echo 'Login';
} else {
print_r($fb->api('/me'));
}
?>
If I visit login.php then visit the page in "1" above - getUser returns the user id and $_SESSION contains the user details.Therefore, I guess the problem is with CodeIgniter but I am not sure how to solve it.
I searched and tried several solutions but that's the best I could do. If possible, I don't want to use the JS SDK.
Thank you
I found a solution and wrote a blog post about it here.
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.
I've been going through FB docs but I think I am totally lost now. My task is quite simple: I need to have an "import" link, user clicks it and receives FB popup where he authorizes the site, user is redirected back to my site, I access user's FB profile and retrieve some data. Also: I need to access and retrieve profile in PHP.
The first part goes well. I created mysite.com?page=import link which opens in popup and then redirects to https://graph.facebook.com/oauth/authorize?...
User then allows access and the popup is redirected back to mysite.com?...#access_token=...&expires_in=4031
Then I am going to close the popup and instead refresh the parent window that opened this popup by redirecting it to something like this mysite.com?page=register&access_token=...&expires_in=4031
Then I was going to use their PHP SDK hoping that it can take this access token and allow me to get user's data. However I have no luck so far. I've tried lots of things and went through facebook.php but can't see a solution. Please let me know how to do this: authorize user in a popup and then gather the profile data in php.
here is your working example.
it has a redirect and works entirely in php, i didnt do javascript beacuse this is easier and faster to write.
the main difference is that the returned code after the authorization page is only a code which allows you to fetch the actual access token incombination with your client secret.
otherwise anyone could get an access token for yuor application or you would have to pass your secret token in the url.
thats the reason for the second step.
in javascript we dont need that because facebook only redirects back to a whitelisted domain
and as the access token is in the url fragment after the # tag the server cant access it, only the client. and this is ensured to be yours erver as your domain must be whitelisted.
but it needs more client interaction...
well anyway. you can use the code i wrote for yuo and you can also do it in a popup. you just have to pass your variables to the form or whatever you are doing but this shouldnt be a problem. i did it this way because you said you needed it in php. a good javascript example can be found on the facebook connect page here: http://developers.facebook.com/docs/guides/web#login
any questions? comment!
ps: i put the # sign before the file_get_contents function because you might geht ssl errors, you should actually use curl for that and do error handling!
save this file as whatever.php to your server, check the 4 config variables in the top and hit it
<?
// your app id
$app_id = "123";
// your secret token
$mysecret = '***';
// your website correctly set up in facebook app config
$redirecturl = "http://www.yourdomain.com/whatever/thisfile.php?action=authorized";
// what you want to fetch
$scopes = array('email','user_interests'); // whatever you want
if($_GET['action'] == 'authorize') {
$url = "https://graph.facebook.com/oauth/authorize?client_id=".$app_id."&redirect_uri=";
$url .= urlencode($redirecturl);
$url .= "&display=popup";
$url .= "&scope=".implode(',',$scopes);
header("Location: $url");
exit();
} else if($_GET['action'] == 'authorized') {
$code = $_GET['code'];
$tokenurl = 'https://graph.facebook.com/oauth/access_token'.
'?client_id='.$app_id .
'&redirect_uri='.urlencode($redirecturl).
'&client_secret='.$mysecret.
'&code='.$code;
$token = #file_get_contents($tokenurl);
$token = preg_match('/access_token=(.*)&/',$token,$extracted_token);
$token = $extracted_token[1];
$dataurl = 'https://graph.facebook.com/me?access_token='.$token;
$result = #file_get_contents($dataurl);
$data = json_decode($result);
echo "<pre>".print_r($data,true)."</pre>";
} else {
?>click here to immport your data<?
}
?>