13

I need to authenticate a Firebase user using node so I can test some server side methods. For each protected request, I verify the Firebase token using:

firebase.auth().verifyIdToken(firebaseAccessToken).then(function(decodedToken) {
    // forward request
})

So in my test I created a token with a uid from my Firebase database

firebase.auth().createCustomToken(uid).then(function(token) {
    //add to header for requests
})

Later I read that custom tokens are not verified by the verifyIdToken method, only client generated ones.

I've looked at this answer - server side verification of tokens in firebase

So I added databaseAuthVariableOverride to the init json

firebase.initializeApp({
  credential: firebase.credential.cert(serviceAccount),
  databaseURL: [dbURL],
  databaseAuthVariableOverride: {
    uid: [uid]
  }
});

Still getting the output in my tests

Error: expected 200 "OK", got 401 "Unauthorized"

And the firebase error -

Error: Decoding Firebase ID token failed. Make sure you passed the entire string JWT which represents an ID token. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.

So how do I emulate a user with my current setup?

Community
  • 1
  • 1
jeh
  • 2,373
  • 4
  • 23
  • 38
  • Maybe this article will help you: https://firebase.googleblog.com/2015/04/end-to-end-testing-with-firebase-server_16.html – Michael Meyer Feb 02 '17 at 15:20

2 Answers2

6

Here's a Python script for generating Firebase ID tokens (not custom tokens).

python firebase_token_generator.py <UID>

There are probably easier ways to do this but you could call the Python script from Node.

J Wang
  • 2,075
  • 1
  • 20
  • 26
4

You can generate a Firebase Id token from your custom token, then use that for verification. Eg:

const rp = require("request-promise");

// 'customToken' comes from FirebaseAdmin.auth().createCustomToken(uid)
function getIdTokenFromCustomToken(customToken) {
    const url = `https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=${API_KEY}`;
    const data = {
        token: customToken,
        returnSecureToken: true
    };

    var options = {
        method: "POST",
        uri: url,
        body: data,
        json: true // Automatically stringifies the body to JSON
    };

    return rp(options)
        // idToken is the firebase id token that can be used with verifyIdToken
        .then(parsedBody => parsedBody.idToken) 
        .catch(function(err) {
            // POST failed...
        });
}
Jeremy
  • 3,438
  • 3
  • 34
  • 57