Strategy | Use Case | Strategy Name |
---|---|---|
local |
Username/password login | 'local' |
jwt |
Token-based auth | 'jwt' |
google |
OAuth login with Google | 'google' |
facebook |
OAuth login with Facebook | 'facebook' |
github |
OAuth login with GitHub | 'github' |
linkedin |
OAuth login with LinkedIn | 'linkedin' |
azure-ad |
SAML or OIDC with Azure AD | 'azure-ad' |
saml |
Enterprise SSO | 'saml' |
anonymous (custom) |
Guest users | 'anonymous' |
2fa (custom) |
Multi-factor authentication | '2fa' |
This allows you to use different strategies on different routes — for example:
/auth/login uses 'local'
/auth/google uses 'google'
/admin/* routes use 'jwt' with admin role checks
nest g resource auth
- with entities, but without test
nest g resource auth --no-spec --type=rest
Example 1: Basic Local Strategy (No users)
// local.strategy.ts
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor() {
super(); // expects 'username' and 'password' in body by default
}
async validate(username: string, password: string): Promise<any> {
// Normally you'd validate against DB here
if (username === 'admin' && password === '1234') {
return { username };
}
return null;
}
}
// local-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
// auth.controller.ts
import { Controller, Post, Req, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './local-auth.guard';
@Controller('auth')
export class AuthController {
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Req() req) {
return req.user;
}
}
// auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { AuthController } from './auth.controller';
@Module({
imports: [PassportModule],
providers: [LocalStrategy],
controllers: [AuthController],
})
export class AuthModule {}
Example 2: Add JWT for Token-based Authentication
// jwt.strategy.ts
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { Injectable } from '@nestjs/common';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'SECRET_KEY',
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}
// auth.service.ts
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(private jwtService: JwtService) {}
async login(user: any) {
const payload = { username: user.username, sub: user.userId };
return {
access_token: this.jwtService.sign(payload),
};
}
}
// auth.controller.ts
import { Controller, Post, Req, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './local-auth.guard';
import { AuthService } from './auth.service';
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
@UseGuards(LocalAuthGuard)
@Post('login')
async login(@Req() req) {
return this.authService.login(req.user);
}
}
// jwt-auth.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
// protected.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';
@Controller('profile')
export class ProfileController {
@UseGuards(JwtAuthGuard)
@Get()
getProfile() {
return { message: 'You are authenticated!' };
}
}
Example 3 Google OAuth with Jwt
Go to https://console.cloud.google.com/apis/credentials:
Create a project and OAuth client ID.
Set redirect URI: http://localhost:3000/auth/google/redirect
Choose Web Application as the client type.
If you want to issue your own JWTs after Google auth, you can:
Generate a JWT in the googleAuthRedirect handler.
Store or register users in a database at that point.
npm install @nestjs/passport passport passport-google-oauth20
npm install @nestjs/jwt passport-jwt --save
//google.strategy.ts
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor() {
super({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: 'http://localhost:3000/auth/google/redirect',
scope: ['email', 'profile'],
});
}
async validate(
accessToken: string,
refreshToken: string,
profile: any,
done: VerifyCallback,
): Promise<any> {
const { name, emails, photos } = profile;
const user = {
email: emails[0].value,
firstName: name.givenName,
lastName: name.familyName,
picture: photos[0].value,
accessToken,
};
done(null, user);
}
}
//auth.controller.ts
import { Controller, Get, Req, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('auth')
export class AuthController {
@Get('google')
@UseGuards(AuthGuard('google'))
async googleAuth() {
// initiates the Google OAuth2 login flow
}
@Get('google/redirect')
@UseGuards(AuthGuard('google'))
googleAuthRedirect(@Req() req) {
// handle the Google OAuth2 callback
return {
message: 'User Info from Google',
user: req.user,
};
}
}
//auth.module.ts
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { AuthController } from './auth.controller';
import { GoogleStrategy } from './google.strategy';
@Module({
imports: [PassportModule],
controllers: [AuthController],
providers: [GoogleStrategy],
})
export class AuthModule {}
//.env
GOOGLE_CLIENT_ID=xxx
GOOGLE_CLIENT_SECRET=xxx
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.