I aim to issue tokens via firebase admin to use for authentication for local development with the emulator.
Using the FireBase Admin targeting a local project(demo-project) in the emulator. The following code is used to lookup a user and issue and validate a token. But this results is a mismatch of the token audience (aud). How could this be resolved ?
Firebase ID token has incorrect audience (aud) claim. Expected demo-project but got https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit. Make sure the ID token comes from the same Firebase project as the credential used to initialize this SDK
Environment.SetEnvironmentVariable("FIREBASE_AUTH_EMULATOR_HOST", "localhost:9099");
Environment.SetEnvironmentVariable("GCLOUD_PROJECT", "demo-project");
var email = [EMAIL];
GoogleCredential dummyCredential =
GoogleCredential.FromAccessToken("test-token");
var app = FirebaseApp.Create(new AppOptions
{
Credential = dummyCredential
});
var auth = FirebaseAuth.GetAuth(app);
var user = await auth.GetUserByEmailAsync(email);
var token = await auth.CreateCustomTokenAsync(user.Uid);
var verifiedToken = await auth.VerifyIdTokenAsync(token);
It seems that the audience depends on how the Admin SDK is initiated, and that is the cause of the mismatch. How should the SDK be initiated for emulator development ? Hoping that it possible to achieve this without any ties to any firebase hosted project.
Wrote two util functions for sign-in, with token or email/password.
Environment.SetEnvironmentVariable("FIREBASE_AUTH_EMULATOR_HOST", "localhost:9099");
Environment.SetEnvironmentVariable("GCLOUD_PROJECT", "demo-project");
var email = [EMAIL];
GoogleCredential dummyCredential =
GoogleCredential.FromAccessToken("test-token");
var app = FirebaseApp.Create(new AppOptions
{
Credential = dummyCredential,
ProjectId = "demo-project"
});
var auth = FirebaseAuth.DefaultInstance;
var user = await auth.GetUserByEmailAsync(email);
var token = await auth.CreateCustomTokenAsync(user.Uid);
var verifiedToken = await auth.VerifyIdTokenAsync(await SignIn.FireBaseSignIn(token));
Instead of using the creating a custom token, signing in an existing user via a sign-in util;
var user = await auth.GetUserByEmailAsync(email);
var verifiedToken = await auth.VerifyIdTokenAsync(await SignIn.FireBaseSignIn(email, [PASSWORD]));
Sign-in utils;
public record SignInResponse(string IdToken);
public static async Task<string> FireBaseSignIn(string email, string password)
{
var authClient = new HttpClient
{
BaseAddress = new Uri("http://localhost:9099/")
};
var res = await authClient.PostAsJsonAsync("identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=fake-api-key",
new { email, password, returnSecureToken = true });
res.EnsureSuccessStatusCode();
var json = await res.Content.ReadFromJsonAsync<SignInResponse>();
return json.IdToken;
}
public static async Task<string> FireBaseSignIn(string token)
{
var authClient = new HttpClient
{
BaseAddress = new Uri("http://localhost:9099/")
};
var res = await authClient.PostAsJsonAsync("identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=fake-api-key",
new { token, returnSecureToken = true });
res.EnsureSuccessStatusCode();
var json = await res.Content.ReadFromJsonAsync<SignInResponse>();
return json.IdToken;
}