Codeigniter, facebook SDK 5, not working - php

I have followed this tutorial https://www.sammyk.me/upgrading-the-facebook-php-sdk-from-v4-to-v5 and so far I have managed to integrate the SDK into codeignitor etc
In my controller I have
function facebook(){
require_once __DIR__ . '/../vendor/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => 'xxx',
'app_secret' => 'xxx',
'default_graph_version' => 'v2.5',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'user_posts']; // optional
$callback = 'http://localhost/project/api/index.php/social/facebook-callback';
$loginUrl = $helper->getLoginUrl($callback, $permissions);
echo $loginUrl;
}
And this generates a url for me. I then follow this link and it takes me to facebook I click ok then it goes to a redirect page.
On that page i have
function facebook_callback(){
require_once __DIR__ . '/../vendor/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => 'xxx',
'app_secret' => 'xxx',
'default_graph_version' => 'v2.5',
]);
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// There was an error communicating with Graph
echo $e->getMessage();
exit;
}
if (isset($accessToken)) {
// User authenticated your app!
// Save the access token to a session and redirect
$_SESSION['facebook_access_token'] = (string) $accessToken;
// Log them into your web framework here . . .
// Redirect here . . .
exit;
} elseif ($helper->getError()) {
// The user denied the request
// You could log this data . . .
var_dump($helper->getError());
var_dump($helper->getErrorCode());
var_dump($helper->getErrorReason());
var_dump($helper->getErrorDescription());
// You could display a message to the user
// being all like, "What? You don't like me?"
exit;
}
// If they've gotten this far, they shouldn't be here
http_response_code(400);
exit;
}
When I land on the page I get as an error
Cross-site request forgery validation failed. Required param "state" missing.
Why does this happen? Is this to do with the sessions? I have followed the tutorial and nothing seems to work. Any other documents I have found I have tried to for example session_start(); and Overwriting Persistent Data but to no avail!
Any point in the right direction will be very much appreciated. I have googled this loads and there are no clear answers.
Best regards

Ok answer found!
Pay special attention to the Overwriting Persistent Data in the tutorial! So it is a session related issue. Also doing it late at night is ill-advised.
What I missed was that you have to start the process from scratch, ie facebook route and get a brand new url link, then paste that link in the url, and you will be redirected to the facebook_callback. And you will then get the data you require.
Answer here incase someone else falls in the "what the hell is going on (when late at night trap)!"

Related

Cant get an accessToken from FB sdk

I would like to get images from my Instagram account to my web page. So I try to use FB php sdk and get accessToken first according this documentation. But it returns null. I don't know what is wrong with the code.
public function getMedia()
{
$fb = new \Facebook\Facebook([
'app_id' => self::APP_ID,
'app_secret' => self::APP_SECRET,
'default_graph_version' => 'v2.10',
//'default_access_token' => '{access-token}', // optional
]);
$helper = $fb->getRedirectLoginHelper(); // Whichever helper I use access-token is null
dd($helper->getAccessToken());
}
I need help with it. It could be so simple.
EDIT:
After few hours I have this, but the last command throws an Facebook\Exceptions\FacebookResponseException Invalid OAuth access token signature. As I see the token is app id and app secret joined with pipe. "733163597544229|xxxxxxxxxxxxx9d14362xxxx3a6". This should work but does not work.
public function getMedia()
{
$fb = new \Facebook\Facebook([
'app_id' => self::APP_ID_FB,
'app_secret' => self::APP_SECRET_FB,
'default_graph_version' => 'v2.10',
//'default_access_token' => '{access-token}', // optional
]);
$token = $fb->getApp()->getAccessToken();
$response = $fb->get('https://graph.instagram.com/me/media?fields=media_url,media_type', $token->getValue());
}
If I've understood the docs correctly, if you want to get an access token dynamically, according to https://developers.facebook.com/docs/facebook-login/web, you need enable fb-login for your app
https://developers.facebook.com/apps/
select your app
add fb-login & follow the tips.
Otherwise you should just be able to get an access token for your app from the web interface and use that over and over.
See also : https://developers.facebook.com/docs/facebook-login/access-tokens#apptokens
There's also:
https://developers.facebook.com/tools/explorer/?method=GET&path=me%3Ffields%3Did%2Cname&version=v9.0
Which enables you to generate an access token, and test out a call to the graph api, AND allows you to export code you can copy/paste:
try {
// Returns a `FacebookFacebookResponse` object
$response = $fb->get(
'/me',
'{access-token}'
);
} catch(FacebookExceptionsFacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
$graphNode = $response->getGraphNode();
EDIT:
I see in your original question you state:
As I see the token is app id and app secret joined with pipe. "733163597544229|xxxxxxxxxxxxx9d14362xxxx3a6". This should work but does not work.
According to the docs, if you want to supply an access token as {app_id}|{client-token} (not sure what secret you're using here) you should append this to the URL, which is not in the URL you're using.
See example here: https://developers.facebook.com/docs/facebook-login/access-tokens#clienttokens
The URL they use is:
curl -i -X GET "https://graph.facebook.com/{your-user-id}/accounts?access_token={user-access-token}
So for you this be:
$response = $fb->get('https://graph.instagram.com/me/media?fields=media_url,media_type&access_token=733163597544229|{client_token}');
EDIT 2:
I managed to get your sample working so perhaps these screen shots will help:
PHP Code:
<?php
$accessToken="EAAJIZAj**************************************************************************************************************************************************************************ZD";
require_once __DIR__ . '/Facebook/autoload.php'; // change path as needed
//echo __DIR__ . '/Facebook/autoload.php';
$fb = new \Facebook\Facebook([
'app_id' => '642**********502',
'app_secret' => '0185*****************f743',
'default_graph_version' => 'v2.10',
'default_access_token' => "{$accessToken}"
]);
try {
// Get the \Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $fb->get('/me');
} catch(\Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
$me = $response->getGraphUser();
echo 'Logged in as ' . $me->getName();
?>
I took the source code from https://github.com/facebookarchive/php-graph-sdk and copied the src/Facebook dir into my project. I amended the path location in my code
require_once __DIR__ . '/Facebook/autoload.php'; // change path as needed
//echo __DIR__ . '/Facebook/autoload.php'; //<< comment out everything else and check the path is correct with this.
Working code: (same as above) with successful output shown at the bottom of the screen shot.
If you need to get the app secret go to the apps settings to uncover it:
Seems you were right - the access token does have an expiry and I had to refresh mine since using it yesterday.
As far as I know this will probably not work to get the access token .
To get access token you need to implement the login with facebook in your app to get the access token . If your app is only used by limited user then you can get access token on this link https://developers.facebook.com/tools/explorer/ but if your app is used by wide range of user and each user has their own data then you need to implement oauth2 in your app

Graph returned an error: Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request

I'm trying to implement facebook login for my website using facebook PHP-SDK with codeigniter by following this example: https://shareurcodes.com/blog/facebook%20php%20sdk%20v5%20with%20codeigniter
From what I have seen from other questions on this subject I checked for given answers/common mistakes but http://localhost/fbcallback is already in my app's Valid OAuth redirect URIs and putting/removing '/' from the end of the url is not helping.
I created two controllers the first one: fblogin.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Fblogin extends CI_Controller{
public function index(){
require_once '{path}/Facebook/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => '{app-id}',
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.5',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email','user_location','user_birthday','publish_actions'];
// For more permissions like user location etc you need to send your application for review
$loginUrl = $helper->getLoginUrl('http://localhost/fbcallback', $permissions);
header("location: ".$loginUrl);
}
}
second one: fbcallback.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
class Fbcallback extends CI_Controller{
public function index(){
require_once '{path}/Facebook/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => '{app-id}',
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.5',
]);
$helper = $fb->getRedirectLoginHelper();
if (isset($_GET['state'])) {
$helper->getPersistentDataHandler()->set('state', $_GET['state']);
}
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
try {
// Get the Facebook\GraphNodes\GraphUser object for the current user.
// If you provided a 'default_access_token', the '{access-token}' is optional.
$response = $fb->get('/me?fields=id,name,email,first_name,last_name,birthday,location,gender', $accessToken);
// print_r($response);
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'ERROR: Graph ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'ERROR: validation fails ' . $e->getMessage();
exit;
}
// User Information Retrieval begins................................................
$me = $response->getGraphUser();
$location = $me->getProperty('location');
echo "Full Name: ".$me->getProperty('name')."<br>";
echo "First Name: ".$me->getProperty('first_name')."<br>";
echo "Last Name: ".$me->getProperty('last_name')."<br>";
echo "Gender: ".$me->getProperty('gender')."<br>";
echo "Email: ".$me->getProperty('email')."<br>";
echo "location: ".$location['name']."<br>";
echo "Birthday: ".$me->getProperty('birthday')->format('d/m/Y')."<br>";
echo "Facebook ID: <a href='https://www.facebook.com/".$me->getProperty('id')."' target='_blank'>".$me->getProperty('id')."</a>"."<br>";
$profileid = $me->getProperty('id');
echo "</br><img src='//graph.facebook.com/$profileid/picture?type=large'> ";
echo "</br></br>Access Token : </br>".$accessToken;
}
}
When I go to http://localhost/fblogin it asks for necessary permissions (email, user location, user birthday , publish actions) but after I give the permissions and redirected to http://localhost/fbcallback I get the following error:
Graph returned an error: Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request.
While I was playing around i realised if I change $loginUrl variables in
vendor/facebook/graph-sdk/src/Facebook/Authentication/OAuth2Client.php to http://localhost/fbcallback as shown below everything works as intended. So I suspected maybe there is a problem while passing the $loginUrl parameter, and traced my code but couldn't find anything problematic.
public function getAuthorizationUrl($loginUrl, $state, array $scope = [], array $params = [], $separator = '&')
{
$params += [
'client_id' => $this->app->getId(),
'state' => $state,
'response_type' => 'code',
'sdk' => 'php-sdk-' . Facebook::VERSION,
'redirect_uri' => 'http://localhost/fbcallback', //instead of {$redirectUrl}
'scope' => implode(',', $scope)
];
What really got me confused is if I change DocumentRoot of my server and copy the above two controllers with the facebook-sdk library everything works just fine again in the new directory. So maybe there is a conflict with one of the files in the current directory? I searched for it but couldn't find anything that may conflict.
Thanks in advance!
The getAccessToken method of the FacebookRedirectLoginHelper generates the API request URL to exchange the code for a token, that includes the redirect_uri parameter.
If this is not explicitly specified as parameter when you call the method, it is determined internally and falls back to the current script URL/route.
So this works without specifying the redirect URI as long as you handle generation of the login URL and processing of the resulting code parameter under the same route resp. under the same script URL; but if those two are different, then you need to specify it when calling getAccessToken.

Issue with facebook login and the php-sdk : callback page is loaded twice

So I posted a question the other day about a bug I was having while trying to implement facebook login using the facebook php-sdk on my site: After changing website domain, facebook login returns error "This authorization code has been used" . I've been getting an error message "This authorization code has been used" on my callback page (see below).
However, I set up a counter (see code below) using a session on the page to see how often it was being loaded. In fact, I found the page was being loaded twice each time I clicked the login button, and therefore the authorisation code is being loaded twice on two pages, resulting in the error. My problem now is solving why the page loads twice. If anyone can tell me I would be very grateful.
If it helps, here is my code.
/index.php
<?php
$fb = new Facebook\Facebook([
'app_id' => '{APP ID}',
'app_secret' => '{APP SECRET}',
'default_graph_version' => 'v2.1',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email']; // Optional permissions
$fbLink = $helper->getLoginUrl('http://{domain}/facebook-callback.php', $permissions);
?>
Login
/facebook-callback.php
<?php
session_start();
//session counter (note: this increments 2 each time, when it should only increment 1)
if (isset($_SESSION["counter"])) {
$_SESSION["counter"] = $_SESSION["counter"]+1;
} else {
$_SESSION["counter"] = 0;
}
echo $_SESSION["counter"];
if (($loader = require_once '/var/www/html/vendor/autoload.php') == null) {
die('Vendor directory not found, Please run composer install.');
}
$fb = new Facebook\Facebook([
'app_id' => '{app id}',
'app_secret' => '{app secret}'
]);
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
}
...
//My code is longer than this but I get the error from the try statement above, so I did not think it necessary to add it here.
?>
Hope I've given enough information. I will praise whoever finds an answer to this, as I've been struggling with it for days now.

Facebook API Session contents randomly changing

So I posted a previous question before about this, but deleted it because I've discovered my problem.
Basically, I was getting this error:
Facebook SDK returned an error: Cross-site request forgery validation failed. The "state" param from the URL and session do not match.
I was able to pinpoint that for some bizarre reason, my $_SESSION['FBRLH_state'] as changing. Here is the login.php that generates the login url for the user:
session_start();
}
require_once $_SERVER['DOCUMENT_ROOT'] . '/src/Facebook/autoload.php';
$fb = new Facebook\Facebook ([
'app_id' => '??????',
'app_secret' => '????',
'default_graph_version' => 'v2.4'
]);
$helper = $fb->getRedirectLoginHelper();
$loginUrl = $helper->getLoginUrl('http://example.ca/login-callback.php');
echo 'Login';
print_r($_SESSION);
When I do a print_r($_SESSION);, I get this:
Array ( [FBRLH_state] => d116b427b433a0b3dc41a858782cd690 )
However (get ready for the magic), upon redirection to the login-callback.php file, the array of $_SESSION mysteriously changes to this:
Array ( [FBRLH_state] => e99c4ece0f8e48ab53dea6a4826c5593 )
Here is the code for login-callback.php
<?php
header("Content-type: text/html;charset=utf-8");
session_start();
print_r($_SESSION);
require_once $_SERVER['DOCUMENT_ROOT'] . '/src/Facebook/autoload.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/Database.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/User.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/vars/constants.php';
//Create the Facebook service
$fb = new Facebook\Facebook ([
'app_id' => '????',
'app_secret' => '????',
'default_graph_version' => 'v2.4'
]);
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
$mysqli = Database::connection();
// Logged in!
$_SESSION['facebook_access_token'] = (string) $accessToken;
When I print $_SESSION (the first thing I do right after the headers), I get a completely different value from the login.php one. It makes no sense because they're both on the same domain (non-www) and they have the same document.cookie PHPSESSID
But, there's a catch. If I press back on login-callback.php (since login.php redirects to it, and then the login fails due to this weird session magic), the $_SESSION values mysteriously match. This doesn't work if I refresh, ONLY when I press back. I think this is some important clue as to what's going on but I have no idea.
Can someone please help me on this extremely frustrating issue? Anyone with any idea of what might be going on?
Edit: Also, I created a blank file with just
session_start();
print_r($_SESSION);
And the values I get always match login-callback.php which means that login.php must be changing some session values (but.... I can't figure out how since when I print_r($_SESSION); at the bottom of the file I still get the same weird values)
Weirdest solution, the problem was solved when I removed the </head> (basically I let <head> be unclosed)

Facebook OAuth, page not found

I've been trying to implement the Facebook OAuth SDK for the past couple of days but keep running into a weird broken link error.
I have followed their instructions on the facebook SDK and used this code for login.php (???? to censor app ID and secret)
$fb = new Facebook\Facebook ([
'app_id' => '????????????????',
'app_secret' => '????????????????',
'default_graph_version' => 'v.2.4'
]);
$helper = $fb->getRedirectLoginHelper();
$loginUrl = $helper->getLoginUrl('http://url.ca/login-callback.php');
This redirects to the login-callback.php file which is what Facebook recommends. Using their provided template code for login-callback.php, mine looks like this:
<?php
session_start();
require_once 'src/Facebook/autoload.php';
//Create the Facebook service
$fb = new Facebook\Facebook ([
'app_id' => '????????????????',
'app_secret' => '????????????????',
'default_graph_version' => 'v.2.4'
]);
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
// Logged in!
$_SESSION['facebook_access_token'] = (string) $accessToken;
// Now you can redirect to another page and use the
// access token from $_SESSION['facebook_access_token']
}
?>
But after being redirected from login.php (clicking on the a href element), I arrive at this:
Sorry, this page isn't available
The link you followed may be broken, or the page may have been removed.
On the Facebook page, no prompt to login, no nothing. I've made my app public already and added this Url to the app as well as ensuring OAuth is enabled, but nothing seems to be working. Does anyone with experience using Facebook OAuth have any idea what's going on?
Is that 'v.2.4' a typo in your question?
The string used in the API should be v2.4 - if you have an extra '.' it's linking you to a URL similar to the real URL of the login dialog, but with an invalid version number in the path

Categories