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';
@Module({
imports: [OAuthModule],
})
export class AppModule {}
# .env
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=http://localhost:3000/oauth/google/callback
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
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';
@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,
};
}
}
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);
}
}
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);
}
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';
}
interface OAuthResponse {
profile: OAuthProfile;
accessToken: string;
refreshToken?: string;
}
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';
@Module({
imports: [
OAuthModule,
OAuthMcpModule.forRoot({
name: 'my-oauth-mcp-server',
version: '1.0.0',
}),
],
})
export class AppModule {}
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
Step 2: Import Module
import { OAuthModule } from 'nestjs-social-auth';
@Module({
imports: [OAuthModule],
})
export class AppModule {}
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
Step 4: Start & Test
npm run start:dev
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..."
}
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:
- π¦ NPM: https://www.npmjs.com/package/nestjs-social-auth
- π» GitHub: https://github.com/cuongdinhngo/nestjs-social-authl providers with three flexible integration approaches.
Top comments (0)