0

I'm having troubles to authenticate from Firebase Cloud Functions to a custom Node server.

Background:

I use a custom node + express server to receive calls from authenticated clients coming from our website. I can successfully verify their tokens using something like this:

const bearerHeader = req.headers['authorization'];
const bearerToken = bearerHeader.split(' ')[1];
await admin.auth().verifyIdToken( bearerToken );

What I need now:

I need to call one of this endpoints but from a Cloud Function (not from an authenticated web client).

So, on the cloud function I'm calling:

const admin = require('firebase-admin');
      admin.initializeApp();  // regular initialization
const token = await admin.app().options.credential?.getAccessToken();
const config = { headers: { Authorization: `Bearer ${token.id_token}` } };
await axios.post(url, body, config);

The problem:

The token.id_token field is missing from getAccessToken():

// token:
{
  access_token: 'ya29. ... ... ',
  expires_in: 3599,
  token_type: 'Bearer'
}

When locally run with other credentials (my user credentials when running firebase functions:shell, for example, or when setting GOOGLE_APPLICATION_CREDENTIALS to a service account credentials file) I do get an extra property id_token that I can use to authenticate. But when deployed and run on the Cloud Function, id_token property is empty.

Any ideas?

Thanks in advance.

PS: an extra problem... the local test with a service account do include id_token, but when authenticating to the server getAccessToken() fails with:

Firebase ID token has incorrect "aud" (audience) claim. Expected "<project-id>" but got "<some-hash>.apps.googleusercontent.com".

Maybe both problems solve the same way. But the server does work properly to verify user tokens coming from a website.

EDIT:

I had to exchange the access_token for an id_token, for which I followed something similar to this, with the projectId as audience. Now the problem is about the issuer (iss) instead of the audience (aud):

Firebase ID token has incorrect "iss" (issuer) claim. Expected "https://securetoken.google.com/<project id>" but got "https://accounts.google.com".

I guess I could verify the token on the server using the same library, but then my web clients would have the same issuer problem

maganap
  • 2,414
  • 21
  • 24
  • Can you try this [1][2] and check if it works for you. [1]https://stackoverflow.com/a/67205708/15803365 [2]https://stackoverflow.com/a/65940148/15803365 – Priyashree Bhadra Aug 02 '21 at 08:33
  • Thank you @PriyashreeBhadra. After reading many similar problems, including those 2 you mention, I ended up solving the "iss" (issuer) mismatch by using the same issuer library on both, client and server. I used `google-auth-library`, though that's not exactly what I wanted because my other clients (real users through our website) were already authenticating using Firebase (which causes the "iss" mismatch if I don't use firebase on the server to verify the token). So I ended up just opening a different path for my could function to authenticate, before executing the rest of the same code. – maganap Aug 02 '21 at 08:52

0 Answers0