@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
Markdown
# 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 /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';
({
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,
) {}
(FirebaseGuard) // This line protects your endpoint. If `validateRole` is enabled, it also validates the user's role.
()
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,
}
('')
export class AppController implements OnModuleInit {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}
()
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,
}
('')
export class AppController {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}
(Roles.ADMIN, Roles.USER) // This line checks the custom claims of the Firebase user to protect the endpoint
(FirebaseGuard) // This line protects your endpoint and, if `validateRole` is enabled, validates the user's role
()
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,
}
('')
export class AppController {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}
()
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 '/nestjs-firebase-auth';
import { auth } from 'firebase-admin';
enum Roles {
ADMIN,
USER,
}
('')
export class AppController {
constructor(
private readonly firebaseProvider: FirebaseProvider,
) {}
(Roles.ADMIN, Roles.USER)
(FirebaseGuard)
()
async mainFunction(
() user: auth.DecodedIdToken,
() 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).