No Auth? No data! Firebase Auth Middleware on Cloud Functions
Protect your Express routes on Firebase Cloud Functions
Firebase Authentication makes it very easy for fresh developers to start thinkering with user auth for their applications. It’s fast to integrate and to manage. They have many auth integrations with providers like Google (of course), Facebook, Twitter, Github.. among others. Phone and email verification capabilities. Too many features to discuss in one story, I’ll try to talk more about other features in future stories, but for now let’s start by implementing a simple secure route for our project.
As we are dealing with Firebase, why not use Cloud Functions for the example. So as usual, while developing our software with our own business logic we will probably need an API, so this article will focus on how can we secure a simple route in our API using the Express web framework on Cloud Functions.
Oh cool, Express in Firebase Cloud Functions
It can be very easy to get going a simple Express setup in Cloud Functions. Express routes are fully supported onfunctions.https
so it’s just plug and play.
Use
functions.https
to create a function that handles HTTP events. The event handler for an HTTP function listens for theonRequest()
event, which supports routers and apps managed by the Express web framework.
Let’s see the example bellow:
We have our first routes setup, now, if we cURL both routes individually they will return the respective response without any barriers. Let’s check out what can we do to protect some endpoints.
Protecting routes
Some endpoints have sensitive content or we need to return user specific data so we must protect them. And we can do just that by making mandatory that the client send an authorization
header so we can check if the request is legit.
That authorization
header will contain the user’s ID Token, retrieved with the help of firebase.auth().currentUser.getIdToken()
, that we will verify in our cloud functions with the methodverifyIdToken
from the Firebase Admin authentication library.
So, to recap, the client will send a token on the headers and we just need to check if it’s valid on the server side. Let’s put it all together:
Adding it to our application to secure the endpoints:
Now we need to update our client to make the requests with the new authorization
header. I’m using axios as the client for demonstration.
Accessing user auth information — whoami
Now that we already have all that we need to secure a route, we just need to tackle one more thing, how to access the user data in the protected routes.
As you may have noticed, we defined a new property in the Express request variable ( auth.js ) that contains the user decoded information:
req.locals = { user: decodedToken }
So we can easily use that in the routes protected by the middleware, like so:
app.get('/whoami', (req, res) => {
res.send({
message: `${req.locals.user.email}, uid: ${req.locals.user.uid}`
})
})
Final Note
Security and user data nowadays is a hard but very important topic and we should pay attention to it. This was a very brief and simplistic approach to secure your routes. There are many more steps to keep our data safe and secure from the threats lurking in the dark, so, try to keep yourself informed and one step ahead. 🍻 Cheers.
Firelayer — Launch your Firebase MVP 10x faster with our templates
Jump-start your Firebase Project with this open source project