Search code examples
facebookmeteoroauthmeteor-accounts

Meteor: Implement facebook package outside of accounts-facebook


I've got a Meteor application with a multi-phase sign-up process. The accounts are based on the accounts-password package. In the step prior to account creation, the user needs to provide some profile information.

I'd like the user to be able to launch a Facebook OAuth flow which pre-populates the profile fields with information pulled from Facebook.

This all needs to happen pre-account-creation. I want to implement this with the facebook package that backs accounts-facebook.

At the moment I've got the OAuth flow happening by calling Facebook.requestCredential, but I'm not sure how to get an OAuth access token from the credential token that comes back. I suspect I need to pass this to the server and make an API call to get back an access token.

Any pointers as to how this should work would be much appreciated.

Facebook.requestCredential(function (credentialTokenOrError) {
  if (credentialTokenOrError && credentialTokenOrError instanceof Error) {
    // Error...
    console.log(credentialTokenOrError);
  } else {
    // Credential Token string
    console.log(credentialTokenOrError);
    // Now perhaps a Meteor.call to a server method that
    // 1. Retrieves an access token
    // 2. Hits the graph API to get profile information and returns it to the client
  }
});

Thanks, Chris


Solution

  • I was having the same trouble of converting a credentialToken to an accessToken, only with Github. I've written up a gist that has code that should work very similarly. Essentially, there are two steps:

    1. Within your Facebook.requestCredential callback function, call OAuth._retrieveCredentialSecret(tokenOrError), the result of which is the credentialSecret. Then use Meteor.call, passing in tokenOrError and credentialSecret, to call the Meteor.method you'll set up in the next step.

    code (on client):

    Github.requestCredential({
      loginStyle: 'popup',
      requestPermissions: ['gist']
    }, function(tokenOrError) {
      if (tokenOrError && tokenOrError instanceof Error) {
        // Throw a Meteor error
        console.log('error getting the token');
        return;
      }
      var credentialSecret = OAuth._retrieveCredentialSecret(tokenOrError);
      Meteor.call('getGithubAccessToken', tokenOrError, credentialSecret, function(err, accessToken) {});
    });
    
    1. On the server, set up a Meteor.method that takes your credentialToken and credentialSecret and calls Facebook.retrieveCredential. This function returns a credentials object from the _pendingCredentials Mongo Collection before deleting it from the collection. The access token is credentials.serviceData.accessToken. The credentials object could potentially be persisted in the user object in the Meteor.users collection (as it is in the accounts packages) or sent back to the user.

    code (on server):

      Meteor.methods({
        getGithubAccessToken: function(credentialToken, credentialSecret) {
          var credentials = Github.retrieveCredential(credentialToken, credentialSecret);
          console.log('accessToken:', credentials.serviceData.accessToken);
          return credentials.serviceData.accessToken;
        }
      });
    

    I'm unfamiliar with the specifics of Facebook's Graph API so after these steps, you're on your own. Good luck!