Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase 3rd-party AuthProvider (Google/Facebook/etc) login with chrome extension manifest v3

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??

like image 397
TechyTech Avatar asked Nov 15 '22 20:11

TechyTech


1 Answers

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...

like image 54
FLUXparticle Avatar answered Jan 11 '23 06:01

FLUXparticle