Search code examples
javascriptreactjsfirebasefirebase-authenticationauth0

Firebase, Auth0, React. The custom token format is incorrect. Please check the documentation


I’m trying to use Auth0 JWT Tokens with Firebase, with no much luck.

When using the token with Firebase:

const token = localStorage.getItem('id_token'); //from auth0
firebase.auth().signInWithCustomToken(token).catch((error) => {
  var errorCode = error.code;
  var errorMessage = error.message;

  console.log(error);
  console.log(token);
});

All I get is:

“The custom token format is incorrect. Please check the documentation.”

As far as I saw in Firebase’s documentation Auth0 and Firebase tokens are different: https://firebase.google.com/docs/auth/admin/create-custom-tokens

Apparently, Firebase expects an uid which is not present in the one generated by Auth0 which uid equivalent is in sub.

I tried to create a rule to modify the Auth0’s token to include a copy of sub named uid to see if this could be a solution, but it’s not working, nothing is added to the body of the token.

function (user, context, callback) {
context.idToken.uid = user.user_id;
callback(null, user, context);
}

Any idea / suggestion?

PS:

1.I checked the token in jwt.io and its valid. 2.I tried reducing the expiring time to less than 5min, as I saw some people considering this a possible solution, but its not.


Solution

  • You can't use an Auth0 token directly with Firebase. You need to create a server-side API that uses the firebase-admin SDK to create a Firebase Custom Token using the Auth0 data.

    There's a full tutorial over on the OAuth site. Check out the API Routes section on how to use firebaseAdmin.auth().createCustomToken given the OAuth token:

    // Auth0 athentication middleware
      const jwtCheck = jwt({
        secret: jwks.expressJwtSecret({
          cache: true,
          rateLimit: true,
          jwksRequestsPerMinute: 5,
          jwksUri: `https://${config.AUTH0_DOMAIN}/.well-known/jwks.json`
        }),
        audience: config.AUTH0_API_AUDIENCE,
        issuer: `https://${config.AUTH0_DOMAIN}/`,
        algorithm: 'RS256'
      });
    
      // Initialize Firebase Admin with service account
      const serviceAccount = require(config.FIREBASE_KEY);
      firebaseAdmin.initializeApp({
        credential: firebaseAdmin.credential.cert(serviceAccount),
        databaseURL: config.FIREBASE_DB
      });
    
      // GET object containing Firebase custom token
      app.get('/auth/firebase', jwtCheck, (req, res) => {
        // Create UID from authenticated Auth0 user
        const uid = req.user.sub;
        // Mint token using Firebase Admin SDK
        firebaseAdmin.auth().createCustomToken(uid)
          .then(customToken => 
            // Response must be an object or Firebase errors
            res.json({firebaseToken: customToken})
          )
          .catch(err => 
            res.status(500).send({
              message: 'Something went wrong acquiring a Firebase token.',
              error: err
            })
          );
      });