So – two previous articles are about integration or Front-end – JavaScript application (in my case it was VueJS app created with Vue CLI).
In this article we will dive deeper and we will integrate our back-end API based on NodeJS (ExpressJS) with Firebase Admin SDK.
Table of Contents
Firebase NodeJS user authentication via web app
You must understand that you can use most of the Firebase services both in front-end JavaScript and back-end NodeJS of your application. In my example – I have integrated in my app with user authentication service. So procedure is as following:
- User opens my application (front-end app in VueJS) and can register a new account and login there. Here only app front-end is integrated with Firebase auth service.
- But we can check only from front-end that user is logged in and give access to some features only on client site.
- In real life – almost always – there is also app back-end in place. So with Firebase admin SDK authentication service we can pass user TOKEN from front-end VueJS app to our back-end NodeJS app, verify directly with Firebase if token is still valid and give access to some protected NodeJS API endpoints.
- But in here the back-end <-> Firebase connection is called FIREBASE ADMIN SDK.
- Summarizing – User login in app front-end, wants to open some protected functionality – user token is sent to back-end, back-end verify that with Firebase Admin SDK and give or refuse access to protected functionality.
You can find whole front-end VueJS app project files HERE ON GITLAB.
Firebase admin SDK with NodeJS app – tutorial
How to do that? Let’s check it step by step how to integrate our NodeJS application with REST API with Firebase for user authentication. Or in details – to verify the user’s privileges to get access to some resources in REST API. Let’s go:
- In your NodeJS API application directory write down:
npm install firebase-admin --save
- Open Firebase console and go:
> Settings > Service Accounts:
https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk
Then we should choose the project, next proceed as in the picture: - When we click “Generate new private key”, we have to save this JSON as a
serviceAccountKey.json
file. REMEMBER, IT IS A PERSONAL DATA FILE, WE SHOULD NOT KEEP IT PUBLIC! - Then we create a new file for example firebase.ts. To this file we copy the content (from above screenshoot), we can also adapt the content to the conditions of our project:
import * as admin from 'firebase-admin'; const serviceAccount = require("./key/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://YOUR-APP-ADDRESS-firebaseio.com" });
- Then we can use all methods of Firebase, look into the documentation, position ADMIN, for example authentication via Firebase admin SDK: https://firebase.google.com/docs/auth/admin and verifying authentication tokens in NodeJS back-end: https://firebase.google.com/docs/auth/admin/verify-id-tokens
- We add the code responsible for authentication token verification to the
firebase.ts
file and export it from the module. In this way, if the token is positively authorized, on the created promise we start resolve with the data received from the Firebase admin SDK request. If the authorization fails, we run the reject with error content.export const verifyIdToken = (idToken: string): Promise<string> => { return new Promise(async (resolve, reject) => { try { const decodedToken = await admin.auth().verifyIdToken(idToken); resolve(decodedToken.uid); } catch (err) { reject(err); } }); }
- After the import into the file from API, for example index.ts, we run it as
async/await/promise.then
, e.g. If it is successfully resolved promise, we perform given request. Unless it is resolved, we return 401 and error content.import * as firebase from './firebase' … try { await firebase.verifyIdToken(req.query.idToken); res.send(products.productsList); next(); } catch (err) { res.statusCode = 401; res.send(err); next(); }
And now we can check via Firebase Admin SDK in our NodeJS app (REST API) if user is authenticated in web app (by token obtained in web app). If yes – than we can allow to open protected resources in NodeJS REST API, if not, return 401 http response.
The Firebase user authentication service is really great because this is very sensitive functionality which we do not need to write by ourselves – the whole protection of user rely on Firebase, we can take it in use and take benefits from that without huge responsibility of hosting in our database user data. Of course we must protect data of currently logged in user, but this is much easier that writing whole Auth 2.0 based on JWT by ourselves.
THE END 🙂