Reputation: 15
Background: I have three entities (language: JS):
So, From 1 and 2, I want to communicate with 3 using HTTPS calls. Because the 3 has admin Auth already, I am able to authorize the calls from clients(1).
But I want to know how I can authorize calls from google cloud functions(2) so that I can securely communicate with both entities.
Token Auth Middleware:
const validateFirebaseIdToken = async (req: any, res: any, next: any) => {
console.log(await auth.getCredentials());
if (
(!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ")) &&
!(req.cookies && req.cookies.__session)
) {
console.log(
"No Firebase ID token was passed as a Bearer token in the Authorization header." +
"Make sure you authorize your request by providing the following HTTP header:" +
"Authorization: Bearer <Firebase ID Token>" +
'or by passing a "__session" cookie.'
);
res.status(403).send("Unauthorized 1");
return;
}
let idToken;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer ")
) {
console.log('Found "Authorization" header');
// Read the ID Token from the Authorization header.
idToken = req.headers.authorization.split("Bearer ")[1];
} else if (req.cookies) {
console.log('Found "__session" cookie');
// Read the ID Token from cookie.
idToken = req.cookies.__session;
} else {
// No cookie
res.status(403).send("Unauthorized 2");
return;
}
try {
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
req.user = decodedIdToken;
next();
return;
} catch (error) {
console.log("Error while verifying Firebase ID token:" + error);
res.status(403).send("Unauthorized 3");
return;
}
};
Upvotes: 1
Views: 783
Reputation: 50840
It sounds like you are trying to make an API call to your server from a Cloud function. If you are using functions.https.onCall
callable function which automatically deserializes the request body and validates auth tokens. So you don't get the actual ID Tokens unless you explicitly pass them.
To pass user info to your server, you can try either of these:
Explicitly pass the ID Token to the cloud function and then to your API which will verify the ID Token again.
As mentioned earler, the callable cloud function will automatically authenticate user and add the DecodedIdToken
to context.auth.token
. As the user is authenticated already you can simply pass the user's UID (and other claims if necessary) to your server for further processing. However, that means you'll have to configure your middleware in such a way that it accepts UID instead of tokens which can be misused by making random requests directly to server with some UIDs.
If you go with method 2, you would have to make sure that the requests are originated from your Cloud function only. This can be done by sharing a secret between cloud function and server and you can just attach that secret to every HTTP request you make to your server similar to an API key.
Upvotes: 3