NestJs: Firebase Auth secured NestJs app using PassportJs
PassportJs is one of the best authentication middleware libraries for NodeJs applications. It supports more than 500 authentication strategies including the most common strategies like username-password, Google, Facebook, Twitter, etc. Its flexibility and ease of integration puts it at the topmost priority when selecting a authentication middleware library for NestJs apps.
If you are using Firebase for your authentication needs, you can use the ‘passport-jwt’ strategy provided by PassportJs. Follow the steps below to know how.
Step#1: Create a Firebase Project
Create a Firebase project and add a web app.
Follow the steps here.
Step#2: Create a NestJs app
Create a NestJs project. I prefer to use Nest CLI for the same. If you do not have Nest CLI, download the package through NPM using the command:
$ npm install -g @nestjs/cli
To create a NestJs app (I am naming my project ‘firebase-auth’; give any name of your choice), open a console in your preferred folder, and run the command:
$ nest new firebase-auth
Step#3: Install PassportJs dependencies
As we know that Firebase generates JSON Web Token (JWT) on authentication, we would be needing ‘passport-jwt’ along with other passport dependencies. Console into the project directory and install these dependencies:
$ npm install @nestjs/passport passport passport-jwt
$ npm install --save-dev @types/passport-jwt
Step#4: Identify your secretKey
passport-jwt requires a ‘secretOrKey’ to verify token’s signature. Firebase uses 2 public keys available here to sign the payloads (refer Firebase doc). The key to be used is identified by the ‘kid’ parameter in the decoded header of a Firebase JWT. Follow these steps to identify your ‘secretOrKey’:
a) Go to https://jwt.io/ and decode your JWT. This will give you a keyId.
b) Search for this keyId here to obtain a public certificate which would be your ‘secretOrKey’:
Step#5: Create an Auth Strategy
Open the project in your favorite IDE. Create a folder, say ‘auth’ inside src. Create your auth strategy extending from passport-jwt strategy. Use the public certificate obtained in the previous step as ‘secretOrKey’. Also, define a validate callback to receive the verified payload as below.
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
(required) directs passport to extract JWT from Authentication header as bearer.
secretOrKey: “<CERTIFICATE>”
(required) specifies the secretKey to verify the JWT’s signature.
async validate(payload) {}
This overridden function ‘validate’ lets you accept the decoded payload and return a custom user object (queried from DB?). This returned object is set to the express request’s ‘user’ field.
Step#6: Provide your Auth Strategy for DI
Provide the AuthStrategy in your AppModule.
Step#7: Enable AuthGuard for your API
Create a controller and enable passport AuthGuard with ‘jwt’ strategy to hook with your API.
Here in the controller method, I am reading the user field from the express request.
Step#8: Create users on Firebase
Create users on Firebase. Also, create any client (VueJs client example) to accept firebase login and obtain a valid firebase idToken. Use this idToken as a Bearer token in the Authorization header of your API calls.
Step#9: Run app and verify
Run you application and verify.
$ npm run dev
Codebase:
https://github.com/sharmavikashkr/firebase-auth-nestjs-passport
Firebase auth in NestJs using Middleware & firebase-admin -> here.