Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HWIOAuthBundle, how to manually authenticate User with a Facebook access token?

I have a website (Symfony2) with HWIOauthBundle used to connect with Facebook and everything works fine.

Now, I'm trying to build an iOS app with Cordova and Ionic framework (AngularJS) and I want to authenticate my user with Facebook :

  1. With $cordovaFacebook, I authenticate my user and get a valid Facebook access token, that's ok

  2. I try to use this access token to authenticate my user on the server-side with HWIOauthBundle :

    GET http://..../login/facebook?code=MY_FACEBOOK_ACCESS_TOKEN
    
  3. Symfony rejects my request with this log :

    INFO - Matched route "facebook_login" (parameters: "_route": "facebook_login")
    INFO - Authentication request failed: OAuth error: "Invalid verification code format."
    

So my question is : how can I authenticate my user on both front and back end with Facebook connect?

Thanks :)

like image 722
Sylvain Avatar asked Apr 27 '15 14:04

Sylvain


People also ask

Does Facebook use token based authentication?

When your app uses Facebook Login to authenticate someone, it receives a User access token. If your app uses one of the Facebook SDKs, this token lasts for about 60 days. However, the SDKs automatically refresh the token whenever the person uses your app, so the tokens expire 60 days after last use.

How do I get to the app token on Facebook?

To get the Client Access Token for an app, do the following: Sign into your developer account. On the Apps page, select an app to open the dashboard for that app. On the Dashboard, navigate to Settings > Advanced > Security > Client token.

How do I use OAuth on Facebook?

Under Products in the App Dashboard's left side navigation menu, click Facebook Login, then click Settings. Verify the Valid OAuth redirect URIs in the Client OAuth Settings section. state . A string value created by your app to maintain state between the request and callback.


2 Answers

I've also been wondering how to implement a server side login with the HWIOAuthBundle. I didn't find any solution on the web, so I coded the functionnality based on hints I've read on the net. Basically, you have to :

  1. authenticate the user on your app
  2. make an http request to your server with the Facebook token.
  3. ont the server side, check if the token is for your Facebook app, and retrieve the user's Facebook ID.
  4. Get your user from the DB based on the fetched ID.

Here's my Symfony controller:

public function getSecurityFbAction($token)
{
    // Get the token's FB app info.
    @$tokenAppResp = file_get_contents('https://graph.facebook.com/app/?access_token='.$token);
    if (!$tokenAppResp) {
        throw new AccessDeniedHttpException('Bad credentials.');
    }

    // Make sure it's the correct app.
    $tokenApp = json_decode($tokenAppResp, true);
    if (!$tokenApp || !isset($tokenApp['id']) || $tokenApp['id'] != $this->container->getParameter('oauth.facebook.id')) {
        throw new AccessDeniedHttpException('Bad credentials.');
    }

    // Get the token's FB user info.
    @$tokenUserResp = file_get_contents('https://graph.facebook.com/me/?access_token='.$token);
    if (!$tokenUserResp) {
        throw new AccessDeniedHttpException('Bad credentials.');
    }

    // Try to fetch user by it's token ID, create it otherwise.
    $tokenUser = json_decode($tokenUserResp, true);
    if (!$tokenUser || !isset($tokenUser['id'])) {
        throw new AccessDeniedHttpException('Bad credentials.');
    }
    $userManager = $this->get('fos_user.user_manager');
    $user = $userManager->findUserBy(array('facebookId' => $tokenUser['id']));

    if (!$user) {
        // Create user and store its facebookID.
    }

    // Return the user's JSON web token for future app<->server communications.
}

I throw the Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException exceptions to handle login errors on my app.

Of course, you really should use https because you will be exchanging sensible information.

I don't know if it's the best way to do it but it works well. Hope it helps !

like image 130
tio oit Avatar answered Nov 15 '22 23:11

tio oit


Well, I think that Symfony doesn't actually reject your request. Facebook is. I'm not sure if this might help, but I know that a bunch a problems can happen when dealing with the Facebook Auth :

  • Do you know if the tool sends, along with the code parameter, a redirect_uri parameter ? If so :

  • Did you check that your redirect_uri HAS a trailing slash at the end ? See this

  • Silly question, but did you check that your app_id is the same when you got authorized via Cordova ?

  • Check that your redirect_uri DOES NOT have any query parameter.

  • Check that the redirect_uri that you use during the whole process is the same all the time.

Overall, it seems that your issue is almost all the time related to the redirect_uri URI format.

like image 31
MeuhMeuh Avatar answered Nov 15 '22 21:11

MeuhMeuh