Sylvain
Sylvain

Reputation: 3070

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 :)

Upvotes: 8

Views: 3019

Answers (2)

tio oit
tio oit

Reputation: 193

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 !

Upvotes: 3

MeuhMeuh
MeuhMeuh

Reputation: 885

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.

Upvotes: 2

Related Questions