Firebase local emulator does not work

Hi there,

I’m trying to use firebase locally for testing, but am unable to get the private key from web3auth for my user. I tried to implement the solution for a similar issue from @irux, (see here: Firebase locally · Web3Auth · Discussion #630 · GitHub) except with flutter instead of vue.

I have a dummy jwks endpoint that is identical to his.

I also have a custom verifier that points to that jwks endpoint and that checks for the aud claim only. I would show you the config for the custom verifier, but I am unable to access the details for some reason:

I sign the unsigned firebase token with the dart_jsonwebtoken package using HS256, and when I decode it, it is identical in structure to the token I get when I don’t use the emulator. dart_jsonwebtoken | Dart Package

But I still get the error that auth shares couldn’t be found.
Here are my details:

  • SDK Version: 1.0.3

  • Screenshots of error:

  • Related to Custom Authentication? Yes

    • Verifier Name: sinbad-local

    • JWKS Endpoint: https://firebasestorage.googleapis.com/v0/b/sinbad-scratch-env.appspot.com/o/jwks-scratch.json?alt=media&token=0788f8cf-75d2-44f1-a4c0-cbcfefdf3d2d
      image

    • Sample idToken(JWT):
      eyJraWQiOiJpZCIsImFsZyI6IkhTMjU2IiwidHlwIjoiSldUIn0.eyJlbWFpbCI6InRlc3RAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1dGhfdGltZSI6MTY4MTM5NDM2MCwidXNlcl9pZCI6InFzd0dvWjQ4eXFudXJFa2RYZHRDcktSQjZyeEwiLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInRlc3RAZ21haWwuY29tIl19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifSwiaWF0IjoxNjgxMzk0Mzg5LCJleHAiOjE2ODEzOTc5ODksImF1ZCI6InNpbmJhZC1zY3JhdGNoLWVudiIsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS9zaW5iYWQtc2NyYXRjaC1lbnYiLCJzdWIiOiJxc3dHb1o0OHlxbnVyRWtkWGR0Q3JLUkI2cnhMIn0.hGFOIHzXs8JIJ5BPOnph-gWBSYM_U095YfxgP5jLZGY

Please provide the Web3Auth initialization and login code snippet below:
local signing of JWT:

login code:

Initialization:

Would be great to get your help on this @gaurav or @shahbaz.

@maseh is it happening on iOS only?

It’s on android and ios

We got it working on local emulator by doing the following:

  1. Switched from HS256 to RS256. This involved a bunch of steps.
  2. You have to generate a pem file. This worked for me on mac.
openssl genrsa -out private_key.pem
  1. Add this to your assets folder and to your pubspec.yaml’s assets folder
assets:
   - assets/your_private_key.pem
  1. From the private key, generate the public key. You can use this command:
openssl rsa -in your_private_key.pem -out your_public_key.pem -pubout
  1. Create a jwk endpoint using the public key on this website, or any tool. Set the public use to signing and algo to RS256, I set the key id to “id”.
    JWK Creator

  2. Take that jwk, and upload it to a public domain, make sure that it’s something easy to change. We made the mistake of putting it on a storage bucket, but those urls can’t be updated, which means you will need to create a new custom verifier, which can take 30 mins - 1.5 hours.

  3. Create a verifier that points to your jwk endpoint with the aud and iss values set to the same values for your cloud firebase instance. We set
    JWT Verifier Id = sub,
    jwk endpoint = yourendpoint.com/yourjwks.json
    jwt validation: {
    aud: your-project-id
    iss: https://securetoken.google.com/your-project-id
    }

  4. In your flutter code, make sure to get your unsigned firebase id token as usual, but then sign it with this method. We used dart_jsonwebtoken (dart_jsonwebtoken | Dart Package) to sign the jwt.

  Future<String> signJwtLocallyForWeb3Auth(String token) async {
    try {
      // return hs256(token);
      return await rs256(token);
    } catch (e) {
      print("Got unexpected exception (will return unmodified token): $e");
      return token;
    }
  }

  Future<String> rs256(String token) async {
    final decodedToken = JWT.decode(token);
    final jwt = JWT(
      decodedToken.payload,
      header: {"kid": "id"},
    );
    final pem = await rootBundle.loadString('assets/your_private_key.pem');
    final key = RSAPrivateKey(pem);
    final signedToken = jwt.sign(key, algorithm: JWTAlgorithm.RS256);
    return signedToken;
  }
}
  1. Make sure your login looks something like this:
      var idToken = (await FirebaseAuth.instance.currentUser!.getIdToken(true))
          .toString();

      print("JWT:$idToken");

      if (isEmulator) {
        print("unsigned JWT:$idToken");
        idToken = await signJwtLocallyForWeb3Auth(idToken);
        print("signed JWT:$idToken");
      }

      final Web3AuthResponse result = await Web3AuthFlutter.login(
        LoginParams(
          mfaLevel: MFALevel.NONE,
          loginProvider: Provider.jwt,
          extraLoginOptions: ExtraLoginOptions(
            id_token: idToken,
            domain: "firebase",
          ),
        ),
      );

and your init code should look something like this:

  final loginConfig = HashMap<String, LoginConfigItem>();
  loginConfig['jwt'] = LoginConfigItem(
      verifier: "your-verifier-name", // get it from web3auth dashboard
      typeOfLogin: TypeOfLogin.jwt,
      name: "firebase",
      clientId: "your-client-id" // web3auth's plug and play client id
      );

  Network web3authNetwork = Network.testnet;

  await Web3AuthFlutter.init(Web3AuthOptions(
      clientId: "your-client-id",
      network: web3authNetwork,
      redirectUrl: redirectUrl,
      loginConfig: loginConfig));

After all this, we got web3auth to work on local emulator

Pls share browser console logs.

@gaurav This was entirely on android and ios, not on the browser

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.