Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I login to Meteor with native device Facebook?

Suppose I logged into my device's Facebook authentication, like system Facebook on iOS. I obtain an access token.

How can I use the access token to login to Meteor's Facebook Oauth provider?

like image 457
DoctorPangloss Avatar asked Dec 05 '25 03:12

DoctorPangloss


1 Answers

To login with Facebook using an access token obtained by another means, like iOS Facebook SDK, define a method on the server that calls the appropriate Accounts method:

$FB = function () {
    if (Meteor.isClient) {
        throw new Meteor.Error(500, "Cannot run on client.");
    }

    var args = Array.prototype.slice.call(arguments);
    if (args.length === 0) {
        return;
    }
    var path = args[0];
    var i = 1;
    // Concatenate strings together in args
    while (_.isString(args[i])) {
        path = path + "/" + args[i];
        i++;
    }

    if (_.isUndefined(path)) {
        throw new Meteor.Error(500, 'No Facebook API path provided.');
    }
    var FB = Meteor.npmRequire('fb');

    var fbResponse = Meteor.sync(function (done) {
        FB.napi.apply(FB, [path].concat(args.splice(i)).concat([done]));
    });

    if (fbResponse.error !== null) {
        console.error(fbResponse.error.stack);
        throw new Meteor.Error(500, "Facebook API error.", {error: fbResponse.error, request: args});
    }

    return fbResponse.result;
};

Meteor.methods({
    /**
     * Login to Meteor with a Facebook access token
     * @param accessToken Your Facebook access token
     * @returns {*}
     */
    facebookLoginWithAccessToken: function (accessToken) {
        check(accessToken, String);

        var serviceData = {
            accessToken: accessToken
        };

        // Confirm that your accessToken is you
        try {
            var tokenInfo = $FB('debug_token', {
                input_token: accessToken,
                access_token: Meteor.settings.facebook.appId + '|' + Meteor.settings.facebook.secret
            });
        } catch (e) {
            throw new Meteor.Error(500, 'Facebook login failed. An API error occurred.');
        }

        if (!tokenInfo.data.is_valid) {
            throw new Meteor.Error(503, 'This access token is not valid.');
        }

        if (tokenInfo.data.app_id !== Meteor.settings.facebook.appId) {
            throw new Meteor.Error(503, 'This token is not for this app.');
        }

        // Force the user id to be the access token's user id
        serviceData.id = tokenInfo.data.user_id;

        // Returns a token you can use to login
        var loginResult = Accounts.updateOrCreateUserFromExternalService('facebook', serviceData, {});

        // Login the user
        this.setUserId(loginResult.userId);

        // Return the token and the user id
        return loginResult;
    }
}

This code depends on the meteorhacks:npm package. You should call meteor add meteorhacks:npm and have a package.json file with the Facebook node API: { "fb": "0.7.0" }.

If you use demeteorizer to deploy your app, you will have to edit the output package.json and set the scrumptious dependency from "0.0.1" to "0.0.0".

On the client, call the method with the appropriate parameters, and you're logged in!

In Meteor 0.8+, the result of Accounts.updateOrCreateUserFromExternalService has changed to an object containing {userId: ...} and furthermore, no longer has the stamped token.

like image 145
DoctorPangloss Avatar answered Dec 06 '25 15:12

DoctorPangloss



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!