13

Manifest version 3 for Chrome extensions have been killing me lately. Been able to navigate around it so far, but this one has really stumped me. I'm trying to use Firebase authentication for a Chrome extension, specifically with 3rd party auth providers such as Google and Facebook. I've setup the Firebase configuration for Login with Google and created a login section in the options page of the Chrome extension and setup the Firebase SDK.

Now, there are two login options when using an auth provider, signInWithRedirect and signInWithPopup. I've tried both of these and both have failed for different reasons. signInWithRedirect seems like a complete dead end as it redirects to the auth provider, and when it attempts to redirect back to the chrome-extension://.../options.html page, it just redirects to "about:blank#blocked" instead.

When attempting to use signInWithPopup, I instead get

Refused to load the script 'https://apis.google.com/js/api.js?onload=__iframefcb776751' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

In v2, you could simply add https://apis.google.com to the content_security_policy in the manifest. But in v3, the docs say

"In addition, MV3 disallows certain CSP modifications for extension_pages that were permitted in MV2. The script-src, object-src, and worker-src directives may only have the following values:"

  • self
  • none
  • Any localhost source, (http://localhost, http://127.0.0.1, or any port on those domains)

So is there seriously no way for a Google Chrome extension to authenticate with a Google auth provider through Google's Firebase? The only workaround I can think of is to create some hosted site that does the authentication, have the Chrome extension inject a content script, and have the hosted site pass the auth details back to the Chrome extension through an event or something. Seems like a huge hack though and possibly subject to security flaws. Anyone else have ideas??

TechyTech
  • 455
  • 2
  • 13
  • ManifestV3 is still half broken despite being promoted as "stable". In the future I see two solutions: a) firebase will provide a compatible auth endpoint, b) `sandbox` value in [CSP](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#content-security-policy) will allow specifying external hosts, https://crbug.com/1220994. – wOxxOm Jul 09 '21 at 09:09
  • 1
    One solution I found that I have yet to try and that only solves fo the Google auth provider case is using chrome.identity to retrieve an auth token which can be used with Firebase in theory. Definitely limiting since I can't use Facebook or any other other provider with this option but at least it's something. – TechyTech Jul 09 '21 at 20:08
  • @TechyTech did you foun solution to this? – rendom Jan 23 '22 at 09:07
  • Sadly no, only the Google auth provider worked in my case – TechyTech Jan 24 '22 at 02:29

1 Answers1

4

Although it was mentioned in the comments that this works with the Google auth provider using chrome.identity sadly there was no code example so I had to figure out myself how to do it.

Here is how I did it following this tutorial:
(It also mentions a solution for non-Google auth providers that I didn't try)

Identity Permission

First you need permission to use the chrome identity API. You get it by adding this to your manifest.json:

{
  ...
  "permissions": [
    "identity"
  ],
  ...
}

Consistent Application ID

You need your application ID consistent during development to use the OAuth process. To accomplish that, you need to copy the key in an installed version of your manifest.json.

To get a suitable key value, first install your extension from a .crx file (you may need to upload your extension or package it manually). Then, in your user data directory (on macOS it is ~/Library/Application\ Support/Google/Chrome), look in the file Default/Extensions/EXTENSION_ID/EXTENSION_VERSION/manifest.json. You will see the key value filled in there.

{
  ...
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgFbIrnF3oWbqomZh8CHzkTE9MxD/4tVmCTJ3JYSzYhtVnX7tVAbXZRRPuYLavIFaS15tojlRNRhfOdvyTXew+RaSJjOIzdo30byBU3C4mJAtRtSjb+U9fAsJxStVpXvdQrYNNFCCx/85T6oJX3qDsYexFCs/9doGqzhCc5RvN+W4jbQlfz7n+TiT8TtPBKrQWGLYjbEdNpPnvnorJBMys/yob82cglpqbWI36sTSGwQxjgQbp3b4mnQ2R0gzOcY41cMOw8JqSl6aXdYfHBTLxCy+gz9RCQYNUhDewxE1DeoEgAh21956oKJ8Sn7FacyMyNcnWvNhlMzPtr/0RUK7nQIDAQAB",
  ...
}

Copy this line to your source manifest.json.

Register your Extension with Google Cloud APIs

You need to register your app in the Google APIs Console to get the client ID:

  1. Search for the API you what to use and make sure it is activated in your project. In my case Cloud Firestore API.
  2. Go to the API Access navigation menu item and click on the Create an OAuth 2.0 client ID... blue button.
  3. Select Chrome Application and enter your application ID (same ID displayed in the extensions management page).
  4. Put this client ID in your manifest.json. You only need the userinfo.email scope.
{
  ...
  "oauth2": {
    "client_id": "171239695530-3mbapmkhai2m0qjb2jgjp097c7jmmhc3.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/userinfo.email"
    ]
  }
  ...
}

Get and Use the Google Auth Token

chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
    // console.log("token: " + token);
    let credential = firebase.auth.GoogleAuthProvider.credential(null, token);
    firebase.auth().signInWithCredential(credential)
        .then((result) => {
            // console.log("Login successful!");
            DoWhatYouWantWithTheUserObject(result.user);
        })
        .catch((error) => {
            console.error(error);
        });
});

Have fun with your Firebase Service...

FLUXparticle
  • 733
  • 6
  • 16
  • Any ideas on implementing this with the Facebook Auth Provider? I've got the Facebook JS SDK included in my extension, and can run FB.init just fine with my app info. However, FB.login does nothing. I expect this has to do with the popup being blocked somehow. – ItJustWerks Sep 28 '22 at 22:33
  • I guess you have to request for permission and open the window manually as described at the bottom of the tutorial I linked. – FLUXparticle Sep 30 '22 at 02:06