Guy
Guy

Reputation: 13286

Firebase auth with NodeJS: getting the UID of the client making the requests

I use NodeJS to communicate with Firebase's Realtime Database.

The rules are defined so only an admin account can read and write:

{
  "rules": {
    ".read": "auth.uid === 'ADMIN_UID'",
    ".write": "auth.uid === 'ADMIN_UID'"
  }
}

When the NodeJS Express server initializes I log in with the admin credentials.

On the web application I use Firebase's "Login with facebook" option:

const provider = new firebase.auth.FacebookAuthProvider();

provider.setCustomParameters({
    display: "popup",
});

firebase
    .auth()
    .signInWithPopup(provider)

Everything works perfectly.

Now, I am trying to extract the User Id (uid) of the user making the requests from the Web Application. When I run the following line:

const user = firebase.auth().currentUser;

I get the admin user rather than the user making the requests. This is expected I guess. My question is how do I get the UserId without sending it explicitly to avoid a security concern?

Upvotes: 1

Views: 2240

Answers (2)

Guy
Guy

Reputation: 13286

I've managed to accomplish this with Firebase Admin SDK.

As described in this guide, you'd need to:

  1. Generate a private key for your service account

    • In the Firebase console, open Settings > Service Accounts.
    • Click Generate New Private Key, then confirm by clicking Generate Key.
    • Securely store the JSON file containing the key.
  2. Set the environment variable

Add to your .bashrc or .zshrc:

 export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"

- In NodeJS initialize the SDK:

admin.initializeApp({
  credential: admin.credential.applicationDefault(),
  databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});

In your client send the JWT token in the header:

const token = await firebase.auth().currentUser.getIdToken()

fetch(url, {
   method: "POST",
   headers: {
      "Content-Type": "application/json",
      Authorization: token
   },
   body: ...
 });

In your server decrypt the token and get the UID:

  return admin
        .auth()
        .verifyIdToken(token)
        .then(function(decodedToken) {
            var uid = decodedToken.uid;
            console.log("uid ->", uid);
            return uid;
        })
        .catch(function(error) {
            console.log("error ->", error);

            // Handle error
        });

That's it. Apparently working with Firebase via your own NodeJS domain is called "using your custom backend". This means the default usage for them is without a NodeJS or other backend middleman.

Upvotes: 4

Flignats
Flignats

Reputation: 1274

Usually with firebase you can include access the context of the request being made and the userId is available.

Something like the following:

context.params.userId

Upvotes: 0

Related Questions