firebase-tools: 8.14.1
Platform: Windows 10
Currently emulating a scenario where a signed in user sends userToken from frontend and backend decoded this token and retrieves uid for fetching data from database.
const firebase = require('firebase/app');
require('firebase/auth');
const config = require('./config/firebaseConfig.json');
const firebaseConfig = {
apiKey: config.apiKey,
authDomain: config.authDomain,
databaseURL: config.projectId,
projectId: config.projectId,
storageBucket: config.storageBucket,
messagingSenderId: config.messagingSenderId,
appId: config.appId,
measurementId: config.measurementId
};
firebase.initializeApp(firebaseConfig);
firebase.auth().useEmulator("http://localhost:9099/");
const serviceAccountKey = require('./config/serviceAccountKey.json');
const admin = require('firebase-admin');
const databaseUrl = `http://localhost:9000/?ns=${config.projectId}`;
admin.initializeApp({
credential: admin.credential.cert(serviceAccountKey),
databaseURL: databaseUrl
});
const perform = async() => {
const email = "[email protected]";
const password = "password";
await admin.auth().createUser({
email: email,
password: password
});
await firebase.auth().signInWithEmailAndPassword(email, password);
const userToken = await firebase.auth().currentUser.getIdToken();
// code fails here where admin is supposed to successfully verify id token
await admin.auth().verifyIdToken(userToken);
};
perform();
make sure that the following node packages are installed and firebase emulators for auth, firestore, and database are enabled:
npm install -g firebase-tools
npm install --save firebase
npm install --save firebase-admin
The userToken is decoded properly so that uid is extracted from the token for fetching data.
It fails with Firebase ID token has no "kid" claim. The code is working normally except when using emulator.
WARNING: You are using the Auth Emulator, which is intended for local testing only. Do not use with production credentials.
(node:24084) UnhandledPromiseRejectionWarning: Error: Firebase ID token has no "kid" claim. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
at FirebaseAuthError.FirebaseError [as constructor]
I'm running into this as well. I can't verify idTokens created by the emulator.
@favs-sama where are you running the admin code?
Right now verifyIdToken() for auth emulator tokens only works inside the Functions emulator. This is out of a concern for security, short-circuiting verifyIdToken() is obviously dangerous if it accidentally happens in production so right now we only allow it in the Functions emulator, which we can control fully.
@samtstern originally i'm running the admin code verifyIdToken() in a backend prehandler function for handling user authorization; so, no i'm not running this inside a firebase function. although is there any other way to approach this kind of testing if currently verifyIdToken() for auth emulator is only accessible via functions emulator?
@favs-sama yeah right now the only way to test this is inside the Functions emulator. We do want to change this eventually but it requires us to build in a more secure version of verifyIdToken() that would be less dangerous to your server in the event of a configuration mistake!
So for now I'll consider this a feature request.
I've created b/172262218 to track this feature request internally
Also running into this. Will be watching this issue.
I changed the name of this issue to more accurately reflect the feature request and include the use case from #2770
I'd need to verify/decode the token with the emulator as well.
@favs-sama where are you running the admin code?
Right now
verifyIdToken()for auth emulator tokens only works inside the Functions emulator. This is out of a concern for security, short-circuitingverifyIdToken()is obviously dangerous if it accidentally happens in production so right now we only allow it in the Functions emulator, which we can control fully.
I was planing to use the auth emulator to do tests without some weird workarounds required at the moment. I think that this behaviour (or at least some imitation of it) should be implemented for testing purposes. This also should have been mentioned at the documentation, would have saved me some time haha
Does anyone have a workaround for this?
@samtstern just voicing my support for this - many, many engineers do not use https.callable and instead opt for express setups, myself included. Not being able to support this means that we have a lack of ability to test our client-server interaction through integration tests.
From an engineering perspective, shouldn't this be as easy as disabling the 'kid' claim check when a certain envvar is set to true (IE, an envvar that is only set when firebase is running emulator mode)? I don't particularly understand why this would be hard to facilitate.
@mjgerace we know how to do this, but we're being extra careful about security. If your production server ever got into a situation where it thought it should disable/skip ID token verification then you'd have a big problem!
In order to have _something_ in time for the launch of the Auth Emulator we compromised on a simple solution in the Node.js Admin SDK that is only enabled inside the Functions emulator. We are actively working on a longer-term solution that we're happier with and when we finish it we will bring it to all of our Admin SDKs (Node, Java, Go, Python, etc) so that you can develop on your own server.
@samtstern this makes total sense - is there any timeline for this work? In the meantime, would it be bad for our team to set an env var (FIREBASE_EMULATOR=1 yarn jest {test_file}) and otherwise workaround the issue in my actual auth middleware?
So long as I can modify the verifyIdToken() function, I could manually implement my suggested fix while I work on testing. Our app isn't in production and this would allow us to write tests without doing anything overly risky.
@mjgerace we never offer timelines but this is something we're actively working on, it's not on the backlog. If you want to work around this issue on your own server and you're confident you know how, go for it!
Most helpful comment
I was planing to use the auth emulator to do tests without some weird workarounds required at the moment. I think that this behaviour (or at least some imitation of it) should be implemented for testing purposes. This also should have been mentioned at the documentation, would have saved me some time haha