Search code examples
javascriptfirebasefirebase-authenticationjwtfirebase-admin

firebase authenticating requests using service account with admin sdk


I am trying to authenticate a server application from a third party using a token generated in my backend using the admin SDK with a service account. For testing purposes, I try to use Postman for the request. I did put the generated token in the header of the postman request by adding Authorization as a header key with the value being Bearer [token] . Unfortunately, when looking in the Firebase log explorer I get the error:

verifyIdToken() expects an ID token, but was given a custom token

This is the code for creating the token:



const admin = require("./firebaseInit");
const uid = "test";

const generateToken = async (req, res) => {
  try {
    // Validation logic
    const isValidService = true; // add more later(testing only)

    if (!isValidService) {
      return res.status(403).json({error: "Invalid service or application"});
    }

    // Set CORS headers
    res.set("Access-Control-Allow-Origin", "https://omnibill-twl.web.app");
    res.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    res.set("Access-Control-Allow-Headers",
        "Origin, Content-Type, Accept, Authorization");


    // Generate a token
    const customToken = await admin.auth().createCustomToken(uid);
    console.log("Custom Token:", customToken);
    res.json({oneTimeToken: customToken});
  } catch (error) {
    console.error("Error generating one-time token:", error);
    res.status(500).json({error: "Internal Server Error"});
  }
};

module.exports = {generateToken};

This is the code which is grabbing the token:

const authHeader = req.header("Authorization");
    const idToken = authHeader ? authHeader.split("Bearer ")[1] : null;

This is the line where it fails with the error:

// Verify the token
    const decodedToken = await admin.auth().verifyIdToken(idToken);

I tried inspecting the generated token on https://jwt.io/ and it states that the signature is invalid. I don't know why because I use the admin sdk and that should automatically sign it with the private key from the JSON file I downloaded from Firebase after creating a new key. I double-checked if the received key is the same as the one which is created and they are matching. I am pretty new to Firebase and JS in general, so sorry if my description is lacking info.


Solution

  • The error message is telling you that you can't use verifyIdToken() to validate a custom token, so what you're trying will never work. That function is for validating user ID tokens coming from a web or mobile app where the user is signed in.

    If you've generated a custom token for your user, you need to use that to sign in the user in your client app with Firebase Auth using signInWithCustomToken(), and after that, you can get an ID token for the user with getToken(). Only that token you can pass to your backend and validate with verifyIdToken().