5

In my project I use a bunch of GCP services, including Firestore, Cloud Functions and Firebase auth.

Taking the fact that users are able to login via Firebase auth service, I assume that it should be possible to check and authenticate users calling my cloud function. Issue is that I can not find any docs or example of how to do that.

I understand that there are special callable functions but it doesn't suit me. I am using express for handling requests.

Is it possible to retrieve some kind of JWT token from user logged in on client side (firebase auth) then send it with request to my cloud function and then check it somehow there? Or is there any other mechanism to achieve CF protection described above?

P.S. I saw this question, but it is not about what I am asking, because it is related to Firebase Functions and I am talking about Cloud Functions which is very similar but not exact same thing.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Artem Arkhipov
  • 7,025
  • 5
  • 30
  • 52
  • Actually, there is no such thing as "Firebase Functions". There is just one product called Cloud Functions. Firebase adds tools and SDKs on top of that, which are called "Cloud Functions for Firebase". The underlying product is exactly the same, and its capabilities are the same no matter which tools you use. You can adapt any solutions found using the Firebase tools for use with Cloud Functions that you deploy with gcloud. – Doug Stevenson May 31 '19 at 13:38
  • I understand that. But Firebase functions are deployed in different way than Cloud functions. Moreover, I am using serverless framework for management and deployment of my functions. Another thing is that I am using express. – Artem Arkhipov May 31 '19 at 13:44
  • Sure, as I mentioned in my answer, you are free to pass data into your function any way you want. It doesn't matter how you deploy it – Doug Stevenson May 31 '19 at 13:45

2 Answers2

19

So, according to Dougs suggestion and after some additional googling I found out the way which should work for me.

On client side we need to retrieve id token of authenticated user:

const token = await firebase.auth().currentUser.getIdToken(true);

Now we can actually add this token to any request we need. I am going to put in request headers while calling my HTTP triggered cloud function. For example:

...
const headers = {
    'Authorization': token
}
const response = await fetch('CF_URL', {headers});
....

The last and most important thing here is to have verification logic on the serverside (Cloud functions in my case):

try {
    const userData = await admin.auth().verifyIdToken(tokenFromHeaders);
    console.log(userData.uid) // here we have uid of verified user
    // check user access or do whatever we need here
} catch (e) {
    // something go wrong
}
Artem Arkhipov
  • 7,025
  • 5
  • 30
  • 52
3

You can very easily duplicate the effect of callable functions by mimicking the protocol that is uses. Just send the user's token in the header of the client request, and parse that out of the headers in your function.

Callable functions use the header Authorization: Bearer <token>, but you are free to do whatever you want. You are just passing data into the function like any other piece of data.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 1
    Thanks, I understand your idea, but docs say that "it must be a POST request". But my functions handle also GET and PUT requests for corresponding functionality (read and update the data from database). – Artem Arkhipov May 31 '19 at 13:47
  • 1
    You are free to use any protocol you want. Passing the token in using a header will work with any HTTP method. Callable functions are implemented with a POST, but you don't have to do that if you don't want. – Doug Stevenson May 31 '19 at 13:48
  • 2
    So the idea is to retrieve token from firebase user on client-side and then use it in headers of further requests. Then I can check it with firebase.admin verification token method? Yes? – Artem Arkhipov May 31 '19 at 13:58
  • Yes, that's what the sample you linked to does. – Doug Stevenson May 31 '19 at 14:15
  • 1
    Thank you for directing me to the right way. – Artem Arkhipov May 31 '19 at 14:16