I have a symfony2 website and a web service secured via oauth using FOSOAuthServerBundle accessible via an iOS app. On the website I use FOSUserBundle and FOSFacebookBundle.
The only thing I miss is giving the possibility to the user to login with facebook on the iOS app and to return him an access_token for my oauth linked to his user account so that he can access my api like other users.
So basically I want to send the user facebookID and facebook_access_token to my webservice, check that the user is correct (token matches my app) and return an authentication token.
QUESTION: is there an easy way to add a "Facebook" grant_type to FOSOAuthServerBundle ?
I know some people have done this seeing these questions:
Design for Facebook authentication in an iOS app that also accesses a secured web service
Get application id from user access token (or verify the source application for a token)
But they do not explain how, they do not seem to use FOSOauthServerBundle and questions are quite old.
I have tried using this bundle: https://github.com/TheFootballSocialClub/FSCOAuth2FacebookGrantBundle
but this bundle has been downloaded only 9 times before me and is not fully suited to my app (it considers that a Facebook user username equals his facebookId for instance). So I guess what I want to do is re-implement the same kind of thing my own way.
If anyone has already done that our could provide any guidance it would be very much appreciated.
Thank you
To do this, you have to add a Grant Extensions, see the official document "Adding Grant Extensions" : https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/blob/master/Resources/doc/adding_grant_extensions.md
You can find my FacebookGrantExtension to get a token from a FB access_token :
class FacebookGrantExtension implements GrantExtensionInterface
{
protected $userManager = null;
protected $facebookSdk = null;
public function __construct(UserManager $userManager, \BaseFacebook $facebookSdk)
{
$this->userManager = $userManager;
$this->facebookSdk = $facebookSdk;
}
/**
* @see OAuth2\IOAuth2GrantExtension::checkGrantExtension
*/
public function checkGrantExtension(IOAuth2Client $client, array $inputData, array $authHeaders)
{
if (!isset($inputData['facebook_access_token'])) {
return false;
}
$this->facebookSdk->setAccessToken($inputData['facebook_access_token']);
try {
// Try to get the user with the facebook token from Open Graph
$fbData = $this->facebookSdk->api('/me');
if (empty($fbData) || !isset($fbData['id'])) {
return false;
}
// Check if a user match in database with the facebook id
$user = $this->userManager->findUserBy(array(
'facebookId' => $fbData['id']
));
// If no user found, register a new user and grant token
if (null === $user) {
return false;
}
// Else, return the access_token for the user
else {
return array(
'data' => $user
);
}
} catch(\FacebookApiExceptionion $e) {
return false;
}
}
}
And the config.yml :
my.oauth.facebook_extension:
class: My\CoreBundle\Oauth\FacebookGrantExtension
arguments:
userManager: "@fos_user.user_manager"
facebookSdk: "@fos_facebook.api"
tags:
- { name: fos_oauth_server.grant_extension, uri: 'http://grants.api.mywebsite.com/facebook_access_token' }