简体   繁体   中英

Using Facebook javascript SDK from extension script

Here is my background.js from a chrome extension:

window.addEventListener("load", function() {
    const fbConnect = new Promise(function(resolve, reject) {
        const script = document.createElement("script");
        script.onload = resolve;
        script.onerror = reject;
        script.async = true;
        script.src = "https://connect.facebook.net/en_US/sdk.js";
        document.body.appendChild(script);
    });
});

window.fbAsyncInit = function() {
    FB.init({
        appId: null,
        version: 'v4.0'
    });

    FB.api("/me", {fields: "last_name"}, function(response) {
        console.log(response);
    });
};

It gives me the following error:

The method FB.api can no longer be called from http pages. https://developers.facebook.com/blog/post/2018/06/08/enforce-https-facebook-login/

What to do now? Is it possible to use this thing from an extension? If so, how can I tell the Facebook server that it's a https request?

Thanks to @misorude and the question he has linked, I have managed to solve this problem, using manual authentication instead of the JS SDK.

It was a pain in the ass to put this together, since the documentation provides poor examples, so I hope it will be useful for others.

Here is the piece of code from the background script:

const options = {
    url: "https://www.facebook.com/dialog/oauth?client_id=<app-id>&response_type=token&redirect_uri=" + browser.identity.getRedirectURL(),
    interactive: true
};
// <app-id> can be found on https://developers.facebook.com/apps/ once you create a new app.
// You must add the URL returned by getRedirectURL() to the app's domain on the page above, otherwise Facebook will return an error.
// getRedirectURL() creates a https:// alias from the extension's browser-extension:// URL.
// The "interactive" key has to be true, otherwise Facebook will return an error.

window.addEventListener("load", function(){
    // Launch the authentication process
    browser.identity.launchWebAuthFlow(options).then(function(url){
        // Mine the access token out of the URL returned by Facebook
        let token = new URL(url).hash.match(/(access\_token=)(.*)(&)/)[2];
        // I don't know why, but the whole query part is served as a hash, so URLSearchParams() won't work.
        // Anyway, the 2nd capture group gives back only the access token string, so we are good.

        // Now we are connected, time to ask some information from Facebook (for example id and name)
        window.fetch("https://graph.facebook.com/me?fields=id,name&access_token=" + token).then(function(response){
            // Parse the response body of the promise
            response.json().then(function(data){
                console.log(data);
                // -> {id: "<your-user-id>", name: "<your-name>"}
            });
        });
    }).catch(function(error){
        console.error(error);
    });
});

I have used the browser namespace of the webExtension platform, but the chrome namespace should work as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM