I am trying to migrate from php-graph-sdk to oauth2-facebook as the first one does not seem to be maintained anymore (no activity on github for 3 years), and the second one seemed easy to use.
For a full web scenario where the user clicks on a Facebook Login button and gets authenticated, everything works fine: when logged out, the library allows me to generate a url for the Login with Facebook button, and the callback allows to generate a token based on the code received.
For a mobile <--> web scenario, things start to break: I am using the Facebook Android and iOS SDK to get an accessToken that I pass to my php script. Then I try to use this accessToken to retrieve the user profile:
require_once "lib/oauth2/autoload.php";
$providerFacebook = new \League\OAuth2\Client\Provider\Facebook([
'clientId' => 'xxxxx',
'clientSecret' => 'xxxxx',
'redirectUri' => 'https://www.foobar.com/login.php',
'graphApiVersion' => 'v3.2',
]);
// Try to look up user profile data with the access token
try
{
$facebook_user = $providerFacebook->getResourceOwner($_POST["accessToken"]); // <-- problem here
// print_r($facebook_user->toArray());
$fb_user = [
"id" => $facebook_user->getId(),
"name" => $facebook_user->getName(),
"email" => $facebook_user->getEmail(),
"picture_url" => $facebook_user->getPictureUrl(),
];
}
catch( \Exception $e )
{
// Failed to get user details
// echo "<!-- ERROR: ".$e->getMessage()." --> ";
}
However this does not work. I could isolate that the following command crash the script (without any error description)
$facebook_user = $providerFacebook->getResourceOwner($_POST["accessToken"]);
The frustrating thing is that the (almost) same code works well if the login starts from the web:
require_once "lib/oauth2/autoload.php";
$providerFacebook = new \League\OAuth2\Client\Provider\Facebook([
'clientId' => 'xxxxx',
'clientSecret' => 'xxxxx',
'redirectUri' => 'https://www.foobar.com/login.php',
'graphApiVersion' => 'v3.2',
]);
// Try to get an access token (using the authorization code grant)
try {
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
} catch (\Exception $e) {
// Failed to get user details
echo $e->getMessage();
exit('Oh my god...');
}
// Try to look up user profile data with the access token
try
{
$facebook_user = $providerFacebook->getResourceOwner($token); // OK!
// print_r($facebook_user->toArray());
$fb_user = [
"id" => $facebook_user->getId(),
"name" => $facebook_user->getName(),
"email" => $facebook_user->getEmail(),
"picture_url" => $facebook_user->getPictureUrl(),
];
}
catch( \Exception $e )
{
// Failed to get user details
// echo "<!-- ERROR: ".$e->getMessage()." --> ";
}
As a reference, my legacy code that works well in both scenarios is the following:
// Facebook
require_once "lib/Facebook/autoload.php";
$fb = new Facebook\Facebook([
'app_id' => 'xxxxx', // Replace {app-id} with your app id
'app_secret' => 'xxxxx',
'default_graph_version' => 'v3.2',
]);
$fb_res = $fb->get('/me?fields=id,name,email,picture.width(600)', $_POST["accessToken"]);
$fb_graph = $fb_res->getGraphUser();
$fb_avatar = json_decode($fb_graph["picture"]);
$fb_user = [
"id" => $fb_graph["id"],
"name" => $fb_graph["name"],
"email" => $fb_graph["email"],
"picture_url" => $fb_avatar->url,
];
$facebook_user = $providerFacebook->getResourceOwner($_POST["accessToken"]);
The getResourceOwner
method expects an AccessToken
instance as parameter, you can not just pass the token value itself as text.
The constructor for \League\OAuth2\Client\Token\AccessToken
takes an array of parameters, providing one containing access_token
should be sufficient here.
$token = new \League\OAuth2\Client\Token\AccessToken(['access_token'=>$_POST["accessToken"]);
$facebook_user = $providerFacebook->getResourceOwner($token);