Skip to content

Instantly share code, notes, and snippets.

@gsabran
Last active November 17, 2017 04:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gsabran/8bab053beb05a0a5bf871b4caa00f9b6 to your computer and use it in GitHub Desktop.
Save gsabran/8bab053beb05a0a5bf871b4caa00f9b6 to your computer and use it in GitHub Desktop.
A route that takes an access token from Facebook as an input and behave consistently with Meteor accounts
import { Accounts } from 'meteor/accounts-base';
import { ServiceConfiguration } from 'meteor/service-configuration';
// currently you need to use a local version of the facebook package with this change:
// https://github.com/meteor/meteor/pull/7550
import { Facebook } from 'meteor/facebook';
import { HTTP } from 'meteor/http';
import { OAuth } from 'meteor/oauth';
/*
* Login with facebook (might create an account)
*/
export const loginWithFacebook = (params, req, res) => {
const { token: fbAccessToken } = req.body;
if (!fbAccessToken) {
return res.respond({ reason: 'Access token is missing', status: 400 });
// res.respond is a custom wrapper that send a formatted response
}
let expiresAt;
try {
expiresAt = JSON.parse(HTTP.get('https://graph.facebook.com/debug_token', {
params: {
input_token: fbAccessToken,
access_token: getAppAccessToken(),
},
}).content).data.expires_at * 1000;
} catch (e) {
return res.respond({ reason: 'fb token is not valid for our app id', status: 401 });
}
const authResult = Facebook.handleAuthFromAccessToken(fbAccessToken, expiresAt);
const { userId } = Accounts.updateOrCreateUserFromExternalService(
'facebook',
authResult.serviceData,
authResult.options
);
// ... do something with the userId from here
res.respond(null, somePayload)
};
/*
* Handle the access token to identify the app with facebook
* (should do it only once since there don't seem to be an expiration)
*/
let appAccessToken = null;
const getAppAccessToken = () => {
if (!appAccessToken) {
try {
const config = ServiceConfiguration.configurations.findOne({ service: 'facebook' });
const response = HTTP.get(
'https://graph.facebook.com/oauth/access_token', {
params: {
client_id: config.appId,
client_secret: OAuth.openSecret(config.secret),
grant_type: 'client_credentials',
},
}).content;
appAccessToken = response.replace('access_token=', '');
} catch (e) {
reportError('Could not set FB app token' + e);
}
}
return appAccessToken;
};
if (!Meteor.isTest && !Meteor.isAppTest) {
// in tests, we need to mock this call first
getAppAccessToken();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment