Harry Lincoln
Harry Lincoln

Reputation: 656

Verifying firebase custom token to get token ID fails when using jsonwebtoken

On the backend a custom token is generated via firebase's admin SDK thusly:

router.use('/get-token', (req, res) => {
    var uid = "big-secret";
    admin.auth().createCustomToken(uid)
      .then(function(customToken) {
        res.json({
          instanceID: customToken
        });
      })
      .catch(function(error) {
        console.log("Error creating custom token:", error);
    });
});

The client frontend app then picks up the customToken and with it makes a request back to the backend to verify:

const fbPrivateKey = serviceAccount.private_key;
const key = new NodeRSA(fbPrivateKey).exportKey('pkcs8-public-pem');
router.get('/verifyIdToken', cors(), (req, res) => {
  jwt.verify(req.headers.authorization.split('Bearer ')[1], key, { algorithms: ['RS256'] }, function(err, decoded) {
    console.log('err', err);
    console.log('decoded', decoded);
  });

This always errors with the message: JsonWebTokenError: invalid signature

Does this need signing? If anyone could explain this or has any pointers?

UPDATE: When running req.headers.authorization.split('Bearer ')[1] through jwt.io is says that the signature is invalid, but then I enter my private key (key) and it validates.

Am I getting the method calls incorrect or passing the wrong arguments into jwt.verify() ?

Upvotes: 19

Views: 19334

Answers (2)

Flavio Rajta
Flavio Rajta

Reputation: 279

If you dont want to use signInWithCustomToken() this is the correct way to do it

const publicKey = new NodeRSA().importKey(serviceAccount.private_key, "pkcs8-private-pem").exportKey("pkcs8-public-pem")

jwt.verify(token, publicKey, {
        algorithms: ["RS256"]
    }, (err, decoded) => {
        if (err) {
            # send some error response
            res.status(400).json({
                status: 0,
                message: "Token is invalid!"
            })
        } else {
            # send some valid response
            res.status(200).json({
                status: 1,
                message: "Token is valid for uid " + decoded.uid
            })
        }
    })

Upvotes: 11

Hiranya Jayathilaka
Hiranya Jayathilaka

Reputation: 7438

It looks like you're calling verifyIdToken with a custom token. That's not going to work. verifyIdToken only accepts "ID tokens". To obtain an ID token from a custom token first call signInWithCustomToken(). Then call getToken() on the signed in user instance.

Upvotes: 25

Related Questions