How to verify a custom token?
Asked Answered
A

2

5

I am using firebase auth and functions for my project. My database api is with a different provider. I need to make some calls to my database from functions as "admin". My server is set up to verify firebase's jwt tokens via following config (custom verification, can't use firebase admin):

{
   "type":"RS256",
"jwk_url":"https://www.googleapis.com/service_accounts/v1/jwk/[email protected]",
   "audience":"<firebase-project-id>",
   "issuer":"https://securetoken.google.com/<firebase-project-id>"
}

This verifies ID Tokens correctly, however fails to parse custom tokens created by admin.auth().createCustomToken with following error:

Could not verify JWT: JWSError JWSInvalidSignature

Hence I can't use custom tokens to authenticate my cloud functions unless I can verify them somehow?

This is how my function token is generated:

  const uid = "function-worker";
  const claims = {
    "https://hasura.io/jwt/claims": {
      "x-hasura-default-role": "function",
      "x-hasura-allowed-roles": ["function"],
      "x-hasura-user-id": uid,
    },
  };
  const jwt = await admin.auth().createCustomToken(uid, claims);

Generated jwt is then send to my hasura server as per https://github.com/hasura/graphql-engine/tree/master/community/sample-apps/firebase-jwt

Following guide above works for id tokens, but not for custom tokens. More detailed explanation for how hasura server handles jwt verification can be found here https://github.com/hasura/graphql-engine/blob/dcab20a5ee388ebd754a7828de1309a3a2e0eaee/docs/graphql/manual/auth/authentication/jwt.rst#generating-jwt-config

Adrell answered 13/5, 2020 at 6:21 Comment(5)
Please edit the question to show the code you're using that doesn't work the way you expect.Grit
@DougStevenson addedAdrell
And how are you verifying it? I was kind of expecting to see some call to verifyIdTokenGrit
@DougStevenson verification is done by hasura graphql server, without using admin sdk, all they ask is to provide json config like I posted above. I believe verification is done here (this is not a language supported by firebase) github.com/hasura/graphql-engine/blob/…Adrell
@DougStevenson here is detailed explanation of how they do it github.com/hasura/graphql-engine/blob/…Adrell
E
7

You can use the Firebase REST API to generate an id token, server side. https://firebase.google.com/docs/reference/rest/auth

Erfert answered 13/5, 2020 at 14:15 Comment(0)
M
1

Generate an id token on firebase functions

1 - REST API

import fetch from 'node-fetch';
...
const customToken = await admin.auth().createCustomToken(user.uid);
const tokenURL = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=';

const response = await fetch(tokenURL + API_KEY, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    token: customToken,
    returnSecureToken: true
  })
}).then(r => r.json());

console.log(response.idToken);

2 - Firebase Client on Server

import firebase from "firebase/app";
import "firebase/auth";

admin.initializeApp();
firebase.initializeApp(firebase_config);
...

const token: any = await admin.auth().createCustomToken(user.uid)
.then((customToken: string) =>
  // use custom token to get firebase token
  firebase.auth().signInWithCustomToken(customToken)
    .then((cred: firebase.auth.UserCredential) => cred.user?.getIdToken()))
.catch((e: string) => console.error(e));
Malina answered 21/4, 2021 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.