DEV Community

Cover image for OAuth Integration in NestJS: From Hours of Configuration to 2 Minutes
Ngo Dinh Cuong
Ngo Dinh Cuong

Posted on

OAuth Integration in NestJS: From Hours of Configuration to 2 Minutes

Let's be honest: implementing OAuth in a NestJS application is more tedious than it should be. You need to:

  • Install multiple Passport strategies (passport-google-oauth20, passport-facebook, passport-linkedin-oauth2, etc.)
  • Create strategy files for each provider with boilerplate code
  • Configure environment variables correctly
  • Set up guards and controllers
  • Handle callback routes
  • Normalize different provider response formats
  • Write tests for each integration

By the time you've added Google, Facebook, LinkedIn, and Apple login, you've written hundreds of lines of repetitive code. And if you need to add another provider later? Start over.

There had to be a better way.

I built nestjs-social-auth to solve this problem once and for all. It's a NestJS library that provides pre-configured OAuth strategies for the most popular social providers with three flexible integration approaches.

Key Features:

  • πŸ” 4 OAuth providers out of the box (Google, Facebook, LinkedIn, Apple)
  • ⚑ 2-minute setup for basic use cases
  • 🎯 3 integration methods (from zero-config to full customization)
  • πŸ€– MCP (Model Context Protocol) support for AI-assisted configuration

The Architecture: Three Integration Paths
One size doesn't fit all. That's why the library offers three distinct integration approaches:

Option 1: OAuthModule (Zero Configuration)

Perfect for getting started quickly. Import the module, set environment variables, and you're done.

// app.module.ts
import { Module } from '@nestjs/common';
import { OAuthModule } from 'nestjs-social-auth';
Enter fullscreen mode Exit fullscreen mode
@Module({
  imports: [OAuthModule],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode
# .env
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/oauth/google/callback
Enter fullscreen mode Exit fullscreen mode

What you get automatically:

  • GET /oauth/:provider - Initiates OAuth flow
  • GET /oauth/:provider/callback - Handles OAuth callback
  • All strategies registered and configured
  • Normalized response format across providers

Under the hood, the library uses:

  • Dynamic Strategy Registration: Strategies are registered only for providers with valid environment variables
  • Strategy Registry Pattern: Maps provider names to their corresponding Passport strategies
  • Dynamic Route Guards: OAuthGuard dynamically selects the correct strategy based on the :provider parameter

Option 2: Integration Command (Full Control)

For teams that want full ownership of the OAuth code:

npx nestjs-social-auth-integrate
Enter fullscreen mode Exit fullscreen mode

This copies the entire src/oauth directory into your project, giving you:

  • Complete source code ownership
  • Full customization capability
  • No dependency on the package for core functionality
  • Easy debugging and modification

Technical benefit: Your OAuth implementation becomes part of your codebase, avoiding potential version conflicts and allowing team-specific modifications.

Option 3: OAuthGuard (Custom Implementation)

For advanced use cases where you need custom endpoints and logic:

import { Controller, Get, Param, UseGuards, Req } from '@nestjs/common';
import { OAuthGuard } from 'nestjs-social-auth';
Enter fullscreen mode Exit fullscreen mode
@Controller('auth')
export class CustomAuthController {
  @Get('login/:provider')
  @UseGuards(OAuthGuard)
  async login(@Param('provider') provider: string) {
    // Guard handles the redirect
  }

  @Get('callback/:provider')
  @UseGuards(OAuthGuard)
  async callback(@Param('provider') provider: string, @Req() req: Request) {
    const user = (req as any).user;

    // Your custom logic: save to DB, generate JWT, etc.
    const token = this.authService.generateToken(user);

    return {
      message: 'Login successful',
      user: user.profile,
      token,
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

Design pattern: The OAuthGuard implements a dynamic guard pattern that inspects the provider parameter at runtime and applies the corresponding Passport strategy.

Technical Deep Dive: How It Works

1. Strategy Registry Pattern

The library uses a centralized strategy registry to map provider names to their Passport strategies:

// Simplified version of the actual implementation
export class StrategyRegistry {
  private strategies = new Map();

  register(provider: string, strategy: any) {
    this.strategies.set(provider, strategy);
  }

  get(provider: string) {
    return this.strategies.get(provider);
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Conditional Strategy Initialization

Strategies are only initialized when their required environment variables are present:

// Only registers if all required env vars exist
if (config.google.clientID && config.google.clientSecret) {
  providers.push(GoogleStrategy);
}
Enter fullscreen mode Exit fullscreen mode

This prevents runtime errors and allows selective provider enablement.

3. Response Normalization

Each provider returns OAuth data in a different format. The library normalizes these into a consistent interface:

interface OAuthProfile {
  id: string;
  email: string;
  firstName: string;
  lastName: string;
  picture: string;
  provider: 'google' | 'facebook' | 'linkedin' | 'apple';
}
Enter fullscreen mode Exit fullscreen mode
interface OAuthResponse {
  profile: OAuthProfile;
  accessToken: string;
  refreshToken?: string;
}
Enter fullscreen mode Exit fullscreen mode

Innovation: MCP Integration

One unique feature is MCP (Model Context Protocol) support, making this the first NestJS OAuth library that AI assistants can understand and help configure.

import { OAuthMcpModule } from 'nestjs-social-auth';
Enter fullscreen mode Exit fullscreen mode
@Module({
  imports: [
    OAuthModule,
    OAuthMcpModule.forRoot({
      name: 'my-oauth-mcp-server',
      version: '1.0.0',
    }),
  ],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

What this enables:

  • AI assistants (like Claude) can query supported providers
  • Get configuration requirements for each provider
  • Receive example environment variable values
  • Understand provider-specific requirements (e.g., Apple's 5-variable setup vs. Google's 3-variable setup)

MCP Tools Available:

  • get_supported_providers - Lists all supported OAuth providers
  • check_provider_support - Validates if a provider is supported
  • get_provider_config_keys - Returns required env vars and examples

This is especially powerful for junior developers or when setting up OAuth in new projects.

Getting Started in 2 Minutes

Step 1: Install

npm install nestjs-social-auth
Enter fullscreen mode Exit fullscreen mode

Step 2: Import Module

import { OAuthModule } from 'nestjs-social-auth';
Enter fullscreen mode Exit fullscreen mode
@Module({
  imports: [OAuthModule],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Environment

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/oauth/google/callback
Enter fullscreen mode Exit fullscreen mode

Step 4: Start & Test

npm run start:dev
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000/oauth/google and you'll be redirected to Google's OAuth page. After authorization, you'll receive:

{
  "profile": {
    "id": "123456789",
    "email": "user@gmail.com",
    "firstName": "John",
    "lastName": "Doe",
    "picture": "https://...",
    "provider": "google"
  },
  "accessToken": "ya29.a0...",
  "refreshToken": "1//0e..."
}
Enter fullscreen mode Exit fullscreen mode

OAuth integration doesn't have to be a multi-day task. With nestjs-social-auth, you can go from zero to working social login in 2 minutes, with the flexibility to customize everything when you need to. Whether you're building your first NestJS app or architecting an enterprise system, having reliable, well-tested OAuth infrastructure lets you focus on what matters: building your product.

Try it out and let me know what you think. And if you're interested in contributing, the community would love to have you! πŸš€

The library is open source and welcomes contributors. Potential areas for contribution:

  • πŸ”§ New Providers: Twitter/X, GitHub, Microsoft, Discord
  • πŸ“š Documentation: More examples, use cases, migration guides
  • πŸ§ͺ Testing: Additional edge cases, integration scenarios
  • 🎨 Features: PKCE support, state validation, custom scopes

Get involved:

Top comments (0)