A comprehensive NestJS with Fastify integration library for Better Auth, providing seamless authentication and authorization for your NestJS applications.
# Using npm
npm install @kylegillen/nestjs-fastify-better-auth
# Using yarn
yarn add @kylegillen/nestjs-fastify-better-auth
# Using pnpm
pnpm add @kylegillen/nestjs-fastify-better-auth
# Using bun
bun add @kylegillen/nestjs-fastify-better-authBefore you start, make sure you have:
- A working NestJS application
- Better Auth installed and configured (installation guide)
Import the AuthModule in your root module:
import { Module } from '@nestjs/common'
import { AuthModule } from '@kylegillen/nestjs-fastify-better-auth'
import { auth } from './auth'
@Module({
imports: [
AuthModule.forRoot({
auth: auth
}),
],
})
export class AppModule {}Below is a valid configuration for asynchronous registration of the module.
import { Module } from '@nestjs/common'
import { AuthModule } from '@kylegillen/nestjs-fastify-better-auth'
import { auth } from './auth'
@Module({
imports: [
AuthModule.forRootAsync({
useFactory: () => {
return auth
}
imports: [],
inject: []
}),
],
})
export class AppModule {}Better Auth provides an AuthGuard to protect your routes. You can choose one of two approaches to implement route protection:
Option 1: Controller or Route Level Protection
Apply the guard to specific controllers or routes:
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard, Optional, Public } from '@thallesp/nestjs-better-auth';
@Controller('users')
@UseGuards(AuthGuard) // Apply to all routes in this controller
export class UserController {
@Get('me')
async getProfile() {
return { message: "Protected route" };
}
@Optional()
@Get('optional')
async getOptional() {
return { message: "Optional route" };
}
@Public()
@Get('public')
async getPublic() {
return { message: "Public route" };
}
}Option 2: Global Protection
Alternatively, you can register the guard globally using APP_GUARD to protect all routes by default:
import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { AuthModule, AuthGuard } from '@thallesp/nestjs-better-auth';
import { auth } from "./auth";
@Module({
imports: [
AuthModule.forRoot(auth),
],
providers: [
{
provide: APP_GUARD,
useClass: AuthGuard,
},
],
})
export class AppModule {}Note
Choose either the controller/route level approach or the global approach based on your needs. You don't need to implement both.
Better Auth provides several decorators to enhance your authentication setup:
Access the user session in your controllers:
import { Controller, Get } from '@nestjs/common';
import { Session, UserSession } from '@thallesp/nestjs-better-auth';
@Controller('users')
export class UserController {
@Get('me')
async getProfile(@Session() session: UserSession) {
return session;
}
}Control authentication requirements for specific routes:
import { Controller, Get } from '@nestjs/common';
import { Public, Optional } from '@thallesp/nestjs-better-auth';
@Controller('users')
export class UserController {
@Get('public')
@Public() // Mark this route as public (no authentication required)
async publicRoute() {
return { message: "This route is public" };
}
@Get('optional')
@Optional() // Authentication is optional for this route
async optionalRoute(@Session() session: UserSession) {
return { authenticated: !!session, session };
}
}Alternatively, use it as a class decorator to specify access for an entire controller:
import { Controller, Get } from '@nestjs/common';
import { Public, Optional } from '@thallesp/nestjs-better-auth';
@Public() // All routes inside this controller are public
@Controller('public')
export class PublicController { /* */ }
@Optional() // Authentication is optional for all routes inside this controller
@Controller('optional')
export class OptionalController { /* */ }