firebase / quickstart-js

Firebase Quickstart Samples for Web
https://firebase.google.com
Apache License 2.0
5.09k stars 3.66k forks source link

Is it possible to share auth between Chrome extension and website? #208

Open torarnv opened 6 years ago

torarnv commented 6 years ago

I have a Chrome extension that uses Firebase authentication (via firebaseui), and a corresponding hosted site that also uses Firebase for authentication (also via firebaseui). How would I go about making the user automatically sign in on the website, if they are already signed in in the Chrome extension?

The extension's authentication lives in its background page, and I can post message from that to the content script, which in turn can post messages to the website (or the other way around), but what do I need to pass over to have the site (which I can control) have enough information to directly sign the user in?

zzpreneur commented 5 years ago

@torarnv Did you find a solution for this?

I'm curious how you got firebaseui working with a chrome extension? The official readme says:

Additional non-browser environments (React Native...) or Chrome extensions will be added once the underlying Firebase core SDK supports them in a way that is compatible with FirebaseUI.

Tinyik commented 4 years ago

Any updates on this? I am having the same question. Thanks!

julienR2 commented 4 years ago

I'm aiming at achieving the same, and I think you could sort it out with custom token https://firebase.google.com/docs/auth/web/custom-auth#authenticate-with-firebase

You'd have to set up a server to handle the authentication and create a custom token, that you can later use this way firebase.auth().signInWithCustomToken(token) Then you can also share this token with you extension to call the same function from there and authenticate your user.

I'll try this solution and get back at you if it works as expected !

julienR2 commented 4 years ago

I've put it to together and it works as expected 👍 Here are the main bits of code:

Firebase function / Auth Server

In a Firebase function (or a custom server) handle the token creation using firebase function createCustomToken

const admin = require('firebase-admin')
const functions = require('firebase-functions')

admin.initializeApp()

module.exports functions.https.onCall(uid =>
  admin.auth().createCustomToken(uid)
)

Webapp

After a successful login, request the server for a custom Token passing the uid of the logged user

firebase.functions().httpsCallable('createToken')(uid)

Then send it to the chrome extension

chrome.runtime.sendMessage(extensionID, token)

Extension

Finally in the extension when receiving a message, log the user with firebase using the custom token

firebase.initializeApp(firebaseConfig)

firebase.auth().onAuthStateChanged(function (user) {
  console.log(
    'User state change detected from the Background script of the Chrome Extension:',
    user
  )
})

chrome.runtime.onMessageExternal.addListener(
  (token, sender, sendResponse) => {
    firebase
      .auth()
      .signInWithCustomToken(token)
      .catch((error) => {
        console.log('error', error)
      })
    return true
  }
)

You background scrip will log the authStateChanged event where you can see that the auth is not isAnonymous anymore and the email attributes is the one of the user logged through your app !

dvrfluxchat commented 2 years ago

Posting so that people like me have to search less. You can use the same approach for Manifest V3.

I was wondering now that in manifest V3 you cannot have long living processes how would you deal with realtime data like firestore?

Danscap commented 2 years ago

Posting so that people like me have to search less. You can use the same approach for Manifest V3.

I was wondering now that in manifest V3 you cannot have long living processes how would you deal with realtime data like firestore?

@dvrfluxchat

I was wondering this, you have an app already implementing the solution from @julienR2 ? Also sorry I cannot answer your firestore question

Thanks so much

dvrfluxchat commented 2 years ago

We are currently developing it and we were able to successfully implement the auth layer though.

julienR2 commented 2 years ago

Glad to read it's working fine with the V3 manifest !

I dug into it for a project that has been dropped since then 😕 It would have been a bit tedious to put it back in place and test it with last version manifest..

My understanding, it works even with manifest v3, because we aren't actually using long-living processes on the extension side, apart maybe for the firebase.auth().onAuthStateChanged ?). Otherwise we are just handling a message from a webpage, and logging the user with the passed token 👍

AyoLaja commented 2 years ago

This was very helpful. Thanks!

mparpaillon commented 2 years ago

You should use "context.auth.uid" inside your callable function instead of a parameter though. Right now you have an exposed function which can give you any user auth token as long as you have their id...

GorvGoyl commented 1 year ago

worth mentioning that custom token expires in 1 hr

Gsonovb commented 1 year ago

Hello everyone, are there any solutions available now?

And how is everyone's CSP set?

PreciousNiphemi commented 11 months ago

chrome.runtime.sendMessage(extensionID, token)

Tried running this in my react application. I keep getting the error below. I am curious if there is something special i have to do to make web app be able to send message to my chrome extension

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'sendMessage')
ivliag commented 7 months ago

worth mentioning that custom token expires in 1 hr

@GorvGoyl, so that means you'll have to sign in again in 1 hour? Is there a workaround?

bma-dev commented 6 months ago

chrome.runtime.sendMessage(extensionID, token)

Tried running this in my react application. I keep getting the error below. I am curious if there is something special i have to do to make web app be able to send message to my chrome extension

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'sendMessage')

@PreciousNiphemi I have the same problem now did you find a solution?

julienR2 commented 6 months ago

Sorry I'm late answering here.. from what I've seen, there's a difference, between injecting a script programmatically, and using an injected.js script.

If you inject programatically, it gives the script access to some of unaccessible property (e.g. chrome.runtime.sendMessage), while if you use the injected.js mechasism, it doesn't, thus the error you're facing.

I think this doc from Chrome page is a good start to read about injecting programatically.

I haven't been working actively with web ext ad firebase auth lately so most of those info are now from memory and quick search. Hopefully it still helps 🤞

caiyongji commented 4 months ago
firebase.functions().httpsCallable('createToken')(uid)

this means everyone got your uid, can create login token without your username and password! this is super danger!!!!

julienR2 commented 4 months ago

Indeed the code I shared at the time didn't cover much the security aspect (I should probably have added a warning).

But it's fairly easy to actually authenticate the firebase function. You could pass the local token, or some authentication key/password along with the uid, to re-authenticating the user in the function, and making sure we are not sending a custom token to anyone who got our uid

Thanks for raising the concern @caiyongji