NestJS Better Auth Module

0.6.4 · maintenance · verified Wed Apr 22

The `nestjs-better-auth` module (version `0.6.4`) integrates the `better-auth` authentication and authorization library into NestJS applications. It provides authentication guards for route protection and decorators for convenient access to authenticated user sessions. This module supports both Express v5 and Fastify HTTP adapters, along with comprehensive GraphQL context capabilities. While it currently maintains CommonJS compatibility, its README indicates a future transition to ESM. This specific package, maintained by `underfisk`, appears to have a slower release cadence compared to a related, more actively developed package (`@thallesp/nestjs-better-auth`) which is at version `2.x.x`. Users should be aware of this distinction when choosing their authentication solution, as `nestjs-better-auth@0.6.4` has not seen recent updates and features like 'Hooks' are still marked 'WIP'.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up `nestjs-better-auth` globally, configure public routes, and access authenticated user sessions within a NestJS application. It includes the crucial step of disabling NestJS's default body parser for proper functionality and showcases the `@CurrentUserSession` decorator.

// main.ts (application entry point)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    // CRITICAL: Disable NestJS's built-in body parser for better-auth to process raw requests.
    bodyParser: false,
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

// app.module.ts (main application module)
import { Module } from '@nestjs/common';
import { BetterAuthModule, BetterAuthGuard, CurrentUserSession, BetterAuthUserSession } from 'nestjs-better-auth';
import { APP_GUARD } from '@nestjs/core'; // Required for global guards
import { Controller, Get, SetMetadata } from '@nestjs/common';

// Define a decorator to mark public routes, bypassing global authentication
const PublicRouteToken = Symbol('publicRoute');
const IsPublic = () => SetMetadata(PublicRouteToken, true);

@Controller()
class MyController {
  @IsPublic()
  @Get('public')
  publicRoute() {
    return { message: 'This route is publicly accessible without authentication.' };
  }

  @Get('me')
  getMe(
    @CurrentUserSession() userAndSession: BetterAuthUserSession,
    @CurrentUserSession('user') user: BetterAuthUserSession['user'],
    @CurrentUserSession('session') session: BetterAuthUserSession['session'],
  ) {
    // In a real app, the BetterAuthGuard would prevent unauthenticated access.
    // Here, we return session details for the authenticated user.
    return { user, session, message: 'Authenticated user session data.' };
  }
}

@Module({
  imports: [
    BetterAuthModule.forRoot({
      // Configure which metadata key marks public routes (to skip global auth)
      skipAuthDecoratorMetadataKey: PublicRouteToken,
      // Provide configuration for the underlying better-auth library
      betterAuthConfig: {
        emailAndPassword: {
          enabled: true, // Example: Enable email and password authentication
        },
        // ... add more better-auth specific configurations here
      },
    }),
  ],
  providers: [
    // Apply BetterAuthGuard globally to protect all routes by default
    {
      provide: APP_GUARD,
      useClass: BetterAuthGuard,
    },
  ],
  controllers: [MyController],
})
export class AppModule {}

view raw JSON →