UNPKG

@alpha018/nestjs-firebase-auth

Version:

NestJS Firebase library and Role based guard for authentication with some utils functions

225 lines (185 loc) 8.09 kB
# NestJS Firebase Auth <div align="center"> <a href="http://nestjs.com/" target="_blank"> <img src="https://nestjs.com/img/logo_text.svg" width="150" alt="Nest Logo" /> </a> </div> <h3 align="center">NestJS Passport Strategy for Firebase Auth using Firebase Admin SDK, which includes the Firebase SDK library for use.</h3> <div align="center"> <a href="https://nestjs.com" target="_blank"> <img src="https://img.shields.io/badge/built%20with-NestJs-red.svg" alt="Built with NestJS"> </a> </div> ## Table of Contents - [Installation](#installation) - [Usage](#usage) - [Import the Module](#import-the-module) - [Parameter Options](#parameter-options) - [Auth Guard Without Role Validation](#auth-guard-without-role-validation) - [Auth Guard With Role Validation](#auth-guard-with-role-validation) - [Additional Information](#additional-information) - [Resources](#resources) - [Stay in touch](#stay-in-touch) - [License](#license) > **⚠️ Important:** Starting from this version, the minimum required Node.js version is **20**, due to the Firebase Admin SDK v12 upgrade. ## Installation ```bash $ npm i @alpha018/nestjs-firebase-auth firebase-admin ``` ## Usage ### Import The Module To use Firebase authentication in your application, import the module into your main module. ```ts import { FirebaseAuthGuard } from '@alpha018/nestjs-firebase-auth'; @Module({ imports: [ ... FirebaseAdminModule.forRootAsync({ imports: [ConfigModule], useFactory: (configService: ConfigService) => ({ // SELECT ONLY ONE: BASE64 OR OPTIONS (Firebase Options)! base64: configService.get('FIREBASE_SERVICE_ACCOUNT_BASE64'), // Base64 encoded service account JSON string options: {}, // Use this if not using base64 auth: { config: { extractor: ExtractJwt.fromAuthHeaderAsBearerToken(), // Choose your extractor from the Passport library checkRevoked: true, // Set to true if you want to check for revoked Firebase tokens validateRole: true, // Set to true if you want to validate user roles useLocalRoles: true, // Set to true if you want to validate user roles locally without firebase call }, }, }), inject: [ConfigService], }), ... ], }) ``` ## Parameter Options | Parameter | Type | Required | Description | |-----------------------------|------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `base64` | `string` | Yes* | Base64 encoded service account JSON string. Required if `options` is not provided. | | `options` | `object` | Yes* | Firebase Admin SDK configuration options. Required if `base64` is not provided. | | `auth.config.extractor` | `function` | Optional | A custom extractor function from the Passport library to extract the token from the request. | | `auth.config.checkRevoked` | `boolean` | Optional | Set to `true` to check if the Firebase token has been revoked. Defaults to `false`. | | `auth.config.validateRole` | `boolean` | Optional | Set to `true` to validate user roles using Firebase custom claims. Defaults to `false`. | | `auth.config.useLocalRoles` | `boolean` | Optional | Set to `true` to validate user roles using local custom claims inside the JWT token. Defaults to `false`. **Note:** If you update the claims, previously issued tokens may still contain outdated roles and remain valid. | ### Auth Guard Without Role Validation To protect an endpoint without validating user roles, use the Auth Guard to ensure the Firebase user's token is valid. ```ts import { FirebaseGuard, FirebaseProvider } from '@alpha018/nestjs-firebase-auth'; export class AppController { constructor( private readonly firebaseProvider: FirebaseProvider, ) {} @UseGuards(FirebaseGuard) // This line protects your endpoint. If `validateRole` is enabled, it also validates the user's role. @Get() mainFunction() { return 'Hello World'; } } ``` ### Auth Guard With Role Validation To enforce role-based access control, you need to set custom claims in Firebase. Here's how you can set custom claims: ```ts import { FirebaseProvider } from '@alpha018/nestjs-firebase-auth'; enum Roles { ADMIN, USER, } @Controller('') export class AppController implements OnModuleInit { constructor( private readonly firebaseProvider: FirebaseProvider, ) {} @Get() async setClaims() { await this.firebaseProvider.setClaimsRoleBase<Roles>( 'FirebaseUID', [Roles.ADMIN, ...] ); return { status: 'ok' } } } ``` Then, use the Auth Guard with role validation to check if a user has the necessary permissions to access an endpoint: ```ts import { FirebaseGuard, FirebaseProvider, RolesGuard } from '@alpha018/nestjs-firebase-auth'; enum Roles { ADMIN, USER, } @Controller('') export class AppController { constructor( private readonly firebaseProvider: FirebaseProvider, ) {} @RolesGuard(Roles.ADMIN, Roles.USER) // This line checks the custom claims of the Firebase user to protect the endpoint @UseGuards(FirebaseGuard) // This line protects your endpoint and, if `validateRole` is enabled, validates the user's role @Get() mainFunction() { return 'Hello World'; } } ``` ### Additional Information To retrieve user claims, use the following example: ```ts import { FirebaseProvider } from '@alpha018/nestjs-firebase-auth'; enum Roles { ADMIN, USER, } @Controller('') export class AppController { constructor( private readonly firebaseProvider: FirebaseProvider, ) {} @Get() async mainFunction() { const claims = await this.firebaseProvider.getClaimsRoleBase<Roles>( 'FirebaseUID', ); return claims; // This returns an array of the user's claims } } ``` To retrieve Decode ID Token and Claims, use the following example: ```ts import { FirebaseGuard, FirebaseProvider, FirebaseUser, FirebaseUserClaims, RolesGuard, } from '@alpha018/nestjs-firebase-auth'; import { auth } from 'firebase-admin'; enum Roles { ADMIN, USER, } @Controller('') export class AppController { constructor( private readonly firebaseProvider: FirebaseProvider, ) {} @RolesGuard(Roles.ADMIN, Roles.USER) @UseGuards(FirebaseGuard) @Get() async mainFunction( @FirebaseUser() user: auth.DecodedIdToken, @FirebaseUserClaims() claims: Roles[], ) { return { user, claims }; } } ``` ## Resources Check out a few resources that may come in handy when working with NestJS: - Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework. - Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com). ## Stay in touch - Author - [Tomás Alegre](https://github.com/Alpha018) ## License Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE).