2

I'm trying to create JWT tokens in node.js for use with the REST api in firebase, but when I try to use them, I get the error "Error: Invalid claim 'kid' in auth header."

This is my code

http.createServer(function (req, res) {
    var payload = {
        uid: "bruh"
    };

    var token = jwt.sign(payload, sact["private_key"], {
        algorithm: 'RS256',
        issuer: sact["client_email"],
        subject: sact["client_email"],
        audience: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
        expiresIn: '3600s',
        jwtid: sact["private_key_id"],
        header: {
            "kid": sact["private_key_id"]
        }
    });

    res.writeHead(200);
    res.end("It worked. (" + token + ")");
}).listen(port);

These are my requires

var http = require('http');
var jwt = require('jsonwebtoken');
Incinirate
  • 114
  • 2
  • 11

3 Answers3

10

Please use returnSecureToken: true, with correct Spellings I hope it will solve the problem of Invalid claim 'kid' in the auth header.

Moiz Ansari
  • 101
  • 1
  • 3
1

This is an issue because you're generating a Firebase ID token, not an access token for the Firebase REST API.

To generate a REST API token I would use the legacy Firebase Token Generator library which still works perfectly well (but only generates REST tokens, not general purpose access tokens).

Note that your Firebase Database secret is now located under the gear icon in the top left of the console.

Abe Haskins
  • 1,378
  • 1
  • 7
  • 9
  • sorry for commenting on old question, but I am getting this error. Is there any updated solution ? – Amir Choubani Sep 30 '19 at 15:06
  • 1
    The answer by Moiz Ansari below helped me solve the issue. The use of the "returnSecureToken: true" in the post body returns the correct token – ashwinlagji Aug 18 '20 at 12:14
0

So I had this error and I've fixed it. Now here is the solution:

You'll need to retrieve the ID-token using an additional function. Here is the function you can use:

firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then(function(idToken) {
  // Send token to your backend via HTTPS
  // ...
}).catch(function(error) {
  // Handle error
}); 

I implemented it somewhat like this:

//google OAuth login handler
    const googleLoginHandler = () => {
        const provider = new firebase.auth.GoogleAuthProvider();
        firebase.auth()
            .signInWithPopup(provider)
            .then((result) => {
                /** @type {firebase.auth.OAuthCredential} */
                setgoogleAuthStatus(true)

                // The signed-in user info.
                const userId = result.user.uid;
                const displayName = result.user.displayName;
                const email = result.user.email;

                //This is the function for getting the ID-Token
                firebase.auth().currentUser.getIdToken(/* forceRefresh */ true).then((idToken) => {
                    // Send token to your backend via HTTPS
                    
                    console.log(idToken)
                }).catch((error) => {
                    // Handle error
                    console.log(error.message)
                    alert(error.message)
                });

                console.log(result)
            }).catch((error) => {
                console.log(error)
                // Handle Errors here.
                alert(error.message)
            })
    }

The id token you get by this method can be used to access the firebase real-time database and other firebase services.

check out these links for more details: https://firebase.google.com/docs/auth/admin/verify-id-tokens#retrieve_id_tokens_on_clients

https://firebase.google.com/docs/database/rest/auth#firebase_id_tokens