Facebook changed their PHP SDK a lot with version 4.0, so i thought you could use a tiny tutorial how to authorize users and how to use the API with the new version. Feel free to comment about any errors or suggestions.
Download/Install/Prerequisites
Obviously, the first thing to do is to download the PHP SDK: Facebook PHP SDK 4
You may also want to take a look at the basic tutorial from Facebook: Getting started with the Facebook SDK for PHP
They even created a fresh repository on github for it. Keep in mind that the old SDK still works (for now), but it´s recommended to use the new one for new projects. So just download the package and upload it to your webserver. You need to upload the whole directory, not just the src folder. Feel free to delete every file except for “autoload.php” in the root folder though, and the folders “docs” and “tests”.
Btw, you can also use Composer, which is the recommended way to install the PHP SDK. But it´s not worth it to use Composer just for one dependency in my opinion, and it would only make things easier/faster if you already got Composer running on your machine. Keep in mind that you don´t need to include autoload.php in that case, Composer takes care of that for you by creating a vendor/autoload.php file to autoload all the dependencies.
AppSecret Proof
One very important security option is to activate the “AppSecret Proof” in the settings of your App. It is easy to use, just activate it and add the “appsecret_proof” parameter to every single call to the Facebook API on the server. Take a look at the Facebook docs for more information: Securing Graph API Requests. You don´t have to care about adding the parameter while using the PHP SDK, it will get added automatically with every call. Check out my article about Extended Page Access Tokens with CURL to see how it looks like to add it on your own.
Keep in mind that this only affects calls on the server, using the JavaScript SDK for API calls still works fine if you activate the AppSecret Proof. So this should ALWAYS be activated to keep your Access Tokens safe.
Using an existing Access Token
Alright, it is time for some code. Login is done best with FB.login in the JavaScript SDK, you can transfer the Access Token to your PHP file and use it with the PHP SDK:
FB.login(function (response) { if (response.authResponse) { console.log(response.authResponse.accessToken); //transfer token to server with ajax } }, {scope: 'email'});
On the server, this is actually the basic example from the PHP SDK, using the transferred Access Token in the highlighted line. There´s one little change though, or it will not work. Not sure if it would work with Composer or if it´s just a bug in the Readme file of the SDK, but line number 5 is missing the “GraphNodes” folder. There you go:
require 'phpsdk4/autoload.php'; use Facebook\FacebookSession; use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphUser; use Facebook\FacebookRequestException; FacebookSession::setDefaultApplication('APP-ID', 'APP-SECRET'); $session = new FacebookSession($_GET['access_token']); try { $me = (new FacebookRequest( $session, 'GET', '/me' ))->execute()->getGraphObject(GraphUser::className()); echo $me->getName(); } catch (FacebookRequestException $e) { // The Graph API returned an error }
As you can see, the code looks a lot more complicated now. A lot of tutorials out there require every single class and make it even more complicated, not sure why they don´t just use the included autoloader. For repeated calls, it would be good to store the Access Token in a session though.
Using the JavaScript Login Helper
You can avoid juggling with Access Tokens by using one of the Helper Classes of the new SDK. The FacebookJavaScriptLoginHelper creates a Session from a JavaScript SDK login process and takes the data from the cookies created by the JavaScript SDK.
The Facebook docs don´t mention something very important: you have to add a cookie parameter to the FB.init call:
FB.init({ appId : 'APP-ID', xfbml : true, version : 'v2.1', cookie : true });
That´s not the only problem, i don´t know if this is the intended way but it seems that you can get the session from the Helper only once – if you need to do more API calls with AJAX and without a page refresh, you have to store the Access Token in a PHP session again. Behold, very long code coming up:
require 'phpsdk4/autoload.php'; use Facebook\FacebookSession; use Facebook\Helpers\FacebookJavaScriptLoginHelper; use Facebook\FacebookRequest; use Facebook\GraphNodes\GraphUser; use Facebook\FacebookRequestException; FacebookSession::setDefaultApplication('APP-ID', 'APP-SECRET'); session_start(); //check for existing session and validate it if (isset($_SESSION['token'])) { $session = new FacebookSession($_SESSION['token']); if (!$session->Validate('APP-ID', 'APP-SECRET')) { unset($session); } } //get new session if (!isset($session)) { try { $helper = new FacebookJavaScriptLoginHelper(); $session = $helper->getSession(); $_SESSION['token'] = $session->getToken(); } catch(FacebookRequestException $e) { unset($session); echo $e->getMessage(); } } //do some api stuff if (isset($session)) { $me = (new FacebookRequest( $session, 'GET', '/me' ))->execute()->getGraphObject(GraphUser::className()); echo $me->getName(); }
I am not sure if this the correct way to use the JavaScript Login Helper, but the docs don´t show a full example and…well, it works 🙂
Using the Page Tab Helper
This Helper Class comes in handy for Page Apps/Tabs, you can mostly use it for getting the signed_request parameter in a convenient way:
require 'phpsdk4/autoload.php'; use Facebook\Helpers\FacebookPageTabHelper; FacebookSession::setDefaultApplication('APP-ID', 'APP-SECRET'); $helper = new FacebookPageTabHelper(); echo '<p>page id: ' . $helper->getPageId() . '</p>'; echo '<p>liked: ' . $helper->isLiked() . '</p>'; echo '<p>admin: ' . $helper->isAdmin() . '</p>';
You obviously can´t use that code with an AJAX call because the signed_request does not magically get transferred to the PHP file.
Important: Like Gating is not allowed anymore and the “liked” parameter will not be available in Apps created after August 7th, 2014. See the Facebook Changelog for more information.
There are actually some more Helper Classes like FacebookCanvasLoginHelper and FacebookRedirectLoginHelper, but i will not cover them here because the Canvas Helper is similar to the page tab helper (without the page data in the signed_request parameter, of course) and the Redirect Helper seems to be there for login with the PHP SDK. Maybe i´ll do a separate article later for it, but I recommend doing all the login stuff with the JavaScript so that´s not important.
If you got any questions, feel free to ask in the comments. Don´t forget to like/share my article if it helped you 🙂
I need help with facebook Actions, permissions and login – do you offer your services – paid of course.
i do, here is my contact info: http://www.devils-heaven.com/imprint/
it works until I log out then log in again. I get the following exception
Error validating access token: The session is invalid because the user logged out.
it should actually renew the session in that case, see “$session->Validate(‘APP-ID’, ‘APP-SECRET’);”
yeah, I commented that line, because I was getting the following error
Facebook\FacebookSDKException
Session has expired, or is not valid for this app.
\FacebookSession.php(207)
// @TODO For v4.1 this should not throw an exception, but just return false.
207 throw new FacebookSDKException(
208 ‘Session has expired, or is not valid for this app.’, 601
209 );
210 }
Thank you
ah, thanx for the information, i will change the code example accordingly.
Hello Andreas,
I got the same error as Fox when I log out then log in again, you mentioned you will change the code example accordingly. Did you finish it? Thanks a lot!
in what code part exactly do you get the error? i am not really updating this thread anymore, since the javascript sdk is so much better and easier for login. i got another article about that on my blog if you are interested.
Hello Andreas,
thanks for your attention.
my question is
below core are in a file,the session got from PHP code did match js’s console. Could you help to figure out the reason? Thanks a lot!
getSession();
var_dump($session);
…….
?>
function statusChangeCallback(response) {
console.log(statusChangeCallback);
console.log(response);
console.log(response.authResponse.accessToken);
if (response.status === ‘connected’) {
var accessToken = response.authResponse.accessToken;
console.log(uid);
console.log(accessToken);
}
………
oh, i did not see that they released version 5 of the php sdk, they must have changed some stuff. i will test it an write a new blogpost, stay tuned.
Hello, this is the first time I try to login to a website with facebook. And I want to log in with the JavaScript SDK and then perform other actions with php. You could put the entire example please ?. And sadly I do not think I’m doing the correct shipping accessToken with ajax .. Thanks and sorry my english
i need help, i will show facebook feed in slide. but i don’t know how. 🙁
you need to be more specific 😉
Thank you,
I make it the same way like you,
but is it possible, to generate an acces token without the js?
yes, it is definitely possible by using “getLoginURL” of the PHP SDK (for example). but as i mention in the article: “I recommend doing all the login stuff with the JavaScript”.
Thank you for this detailed post!
One gotcha I found was that if you want to use the FacebookSession method “getUserId” one has to save the raw signed request in the $_SESSION also like this (using PHP Facebook SDK 4.0.12):
$_SESSION[‘rawSignedRequest’] = $session->getSignedRequest()->getRawSignedRequest();
Then you can make your session like this:
if (isset($_SESSION[‘token’]) && isset($_SESSION[‘rawSignedRequest’])) {
$signedRequest = new SignedRequest($_SESSION[‘rawSignedRequest’], null, $APP_SECRET);
$session = new FacebookSession($_SESSION[‘token’], $signedRequest);
Now $session->getUserId() returns something useful 🙂
Hello, could you please help me with a really simple (for you) task. I am trying to get permisions only with php. Without the use of javascript. And i am trying to do it for a facebook app (Canvas Page) and for a facebook tab (Tab Page).
I cannot get the getLoginUrl to work.
My code looks like this:
FacebookSession::setDefaultApplication( $fbconfig[‘appid’],$fbconfig[‘secret’] );
$scope = array(‘manage_pages, read_stream’);
$helper = new FacebookRedirectLoginHelper(‘https://www.facebook.com/TestingPagexxx/app_38909853xxx’);
$loginUrl = $helper->getLoginUrl($scope);
echo ‘Login a‘;
that´s a bit too broad for helping you in a serious way, and i really suggest using the javascript sdk for this. it may be better to post your problem on stackoverflow with all the code.
btw, you should forget about read_stream, it will most likely not get approved in the review process.
The “read_stream” is just an example, i cannot get the $session = $helper->getSessionFromRedirect() to work even with no extra permissions at all. Thanks anyway 🙂
Hello Andreas,
I’ve followed your great tutorials in order to manage a Facebook Login Flow on my Website. I allow the login with Javascript and then I want ship the token to the php server by using the JavascriptHelper.
Assuming to make exactly what you’re doing here, what I should expect as a result?
For example assuming there’s “html1” with the javascript login. Here everything work fine. Then there’s a “login.php” file in which I wrote exactly what you suggested in your tutorial.
Now, how can I make sure everything is working? What to expect? I thought that when someone click on Facebook login button, on “myhost.com/login.php” would have appeared his name. But it still stays blank.
Although I’ve read tons of documentation and tutorials, I think I didn’t really get right how the javascript part and the php part are bound together. As far as I got it, there’s no evidence on the Javacript that refers to that specific php page, neither there’s the other way around. Can you clarify this point a little bit for me, please?
Thank you again for your effort and awesome materials.
Greets,
Giacomo
well, it depends what you want to achieve/get. in most cases you may not even need php, you definitely don´t need it just for login.
I’m doing a thesis project. Basically, I need to make around 150 users (friends) login on my website and get some of their data in order to extrapolate some of their personality traits.
My flow is they do the login and then make a questionary. Meanwhile I need their long-lived access token and store them in a Database in order to retrieve their data over time.
Anyway, I’ve posted a question on stack overflow:
http://stackoverflow.com/questions/18227439/use-php-namespace-inside-function
There’s my code over there, maybe you know how to reply to my answer.
Basically I want to know if I need ajax code or everything is handled by the helper.. And how?
Again, a huge thanks for all your help. I’ll mention on my thesis 😀
Sorry.. this is the link:
http://stackoverflow.com/questions/28234311/facebook-sdk-how-to-use-javascriptloginhelper
Check it out if you have time!
Cheers
Ok, I finally found a way to manage the issues a little bit. Right now I get fatal error 500. Looking at the error log on the server i obtain that the issue is:
PHP Fatal error: Class ‘Facebook\\FacebookSession’ not found in /var/www/html/script/login.php on line 24
I tried to fix but I failed. How can I ?
well, i assume you fixed the error already, according to stackoverflow 🙂
btw, i would just forget about the php sdk and use basic curl calls instead, here´s an example how to generate extended page tokens that way – extended user tokens are needed for that, so it´s even more than you need: http://www.devils-heaven.com/extended-page-access-tokens-curl/
Thank you so much for the concept… <3
$session = $helper->getSession();
$_SESSION[‘token’] = $session->getToken();
How can this code work if $session = method and can`t run other method $session->getToken()..??
sorry for my english
i am not sure what you mean, do you get any error/exception? could also be that they have changed stuff since then, i need to test with the latest sdk version.
Fatal error: Call to a member function getToken() on a non-object in.
$helper->getSession(); return session or NULL (https://developers.facebook.com/docs/php/FacebookJavaScriptLoginHelper/4.0.0#instance-methods)
Hey,
First I have to say that I learned a lot in your tutorial.
I’m not sure if this is told by anybody but the FacebookPageTabHelper doesn’t worked for me. After a long time of work I recognize that:
use Facebook\Helper\FacebookPageTabHelper;
have to be
use Facebook\FacebookPageTabHelper;
so
use Facebook\
Helper\FacebookPageTabHelper;After I changed this it work fine.
Best regards
Karl
Thanks for a lot secret information that The Facebook docs don´t mention 😀
Hi, could you explain how to “transfer token to server with ajax”?
I trying and reading a lot of examples on internet, but without successful 🙁
Thanks in advice.
google for ajax, there are plenty of good tutorials out there. you can send a token as POST variable to a php script, google for that exactly.
Thank you so much! You saved me with the “cookie: true” on FB.init