Created
May 16, 2023 19:57
-
-
Save System3-2/aefdf449e51e7f8e9d30eb2cd3fda7c0 to your computer and use it in GitHub Desktop.
Nestjs authentication strategy public
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm install --save @nestjs/passport passport-jwt passport-google-oauth20 passport-github2 | |
import { Injectable } from '@nestjs/common'; | |
import { PassportStrategy } from '@nestjs/passport'; | |
import { ExtractJwt, Strategy } from 'passport-jwt'; | |
import { AuthService } from '../auth.service'; | |
@Injectable() | |
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { | |
constructor(private authService: AuthService) { | |
super({ | |
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), | |
ignoreExpiration: false, | |
secretOrKey: 'secret', | |
}); | |
} | |
async validate(payload: any) { | |
const user = await this.authService.validateUser(payload.username); | |
return user; | |
} | |
} | |
import { Injectable } from '@nestjs/common'; | |
import { PassportStrategy } from '@nestjs/passport'; | |
import { Strategy } from 'passport-google-oauth20'; | |
import { AuthService } from '../auth.service'; | |
@Injectable() | |
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') { | |
constructor(private authService: AuthService) { | |
super({ | |
clientID: 'google_client_id', | |
clientSecret: 'google_client_secret', | |
callbackURL: 'http://localhost:3000/auth/google/callback', | |
scope: ['profile'], | |
}); | |
} | |
async validate(accessToken: string, refreshToken: string, profile: any, done: any) { | |
const user = await this.authService.validateOAuthUser('google', profile.id); | |
done(null, user); | |
} | |
} | |
import { Injectable } from '@nestjs/common'; | |
import { PassportStrategy } from '@nestjs/passport'; | |
import { Strategy } from 'passport-github2'; | |
import { AuthService } from '../auth.service'; | |
@Injectable() | |
export class GithubStrategy extends PassportStrategy(Strategy, 'github') { | |
constructor(private authService: AuthService) { | |
super({ | |
clientID: 'github_client_id', | |
clientSecret: 'github_client_secret', | |
callbackURL: 'http://localhost:3000/auth/github/callback', | |
}); | |
} | |
async validate(accessToken: string, refreshToken: string, profile: any, done: any) { | |
const user = await this.authService.validateOAuthUser('github', profile.id); | |
done(null, user); | |
} | |
} | |
import { ExecutionContext, Injectable } from '@nestjs/common'; | |
import { AuthGuard } from '@nestjs/passport'; | |
@Injectable() | |
export class MultiAuthGuard extends AuthGuard(['jwt', 'google', 'github']) { | |
canActivate(context: ExecutionContext) { | |
return super.canActivate(context); | |
} | |
} | |
import { Controller, Get, UseGuards } from '@nestjs/common'; | |
import { MultiAuthGuard } from './guards/multi-auth.guard'; | |
@Controller() | |
export class AppController { | |
@Get('protected') | |
@UseGuards(MultiAuthGuard) | |
protectedRoute() { | |
return 'Protected route'; | |
} | |
} | |
npm install --save @nestjs/passport passport-jwt | |
import { Injectable } from '@nestjs/common'; | |
import { PassportStrategy } from '@nestjs/passport'; | |
import { ExtractJwt, Strategy } from 'passport-jwt'; | |
import { AuthService } from '../auth.service'; | |
import { JwtBlacklistService } from './jwt-blacklist.service'; | |
@Injectable() | |
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { | |
constructor(private authService: AuthService, private jwtBlacklistService: JwtBlacklistService) { | |
super({ | |
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), | |
ignoreExpiration: false, | |
secretOrKey: 'secret', | |
}); | |
} | |
async validate(payload: any) { | |
const tokenIsBlacklisted = await this.jwtBlacklistService.tokenIsBlacklisted(payload.jti); | |
if (tokenIsBlacklisted) { | |
throw new Error('Invalid token'); | |
} | |
const user = await this.authService.validateUser(payload.username); | |
return user; | |
} | |
} | |
import { Injectable } from '@nestjs/common'; | |
@Injectable() | |
export class JwtBlacklistService { | |
private readonly blacklist: Set<string> = new Set(); | |
addToBlacklist(tokenId: string, expiresIn: number) { | |
this.blacklist.add(tokenId); | |
setTimeout(() => { | |
this.blacklist.delete(tokenId); | |
}, expiresIn * 1000); | |
} | |
async tokenIsBlacklisted(tokenId: string) { | |
return this.blacklist.has(tokenId); | |
} | |
} | |
@Injectable() | |
export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { | |
// ... | |
public readonly name = 'jwt'; | |
// ... | |
} | |
@Injectable() | |
export class GoogleStrategy extends PassportStrategy(OAuth2Strategy, 'google') { | |
// ... | |
public readonly name = 'google'; | |
// ... | |
} | |
@Injectable() | |
export class GithubStrategy extends PassportStrategy(OAuth2Strategy, 'github') { | |
// ... | |
public readonly name = 'github'; | |
// ... | |
} | |
@Controller('auth') | |
export class AuthController { | |
constructor(private jwtBlacklistService: JwtBlacklistService) {} | |
@Post('logout') | |
@UseGuards(AuthGuard('jwt'), AuthGuard('google'), AuthGuard('github')) | |
async logout(@Request() req: any, @Query('strategy') strategy: string) { | |
switch (strategy) { | |
case 'jwt': | |
const tokenId = req.user.jti; | |
const expiresIn = req.user.exp - req.user.iat; | |
this.jwtBlacklistService.addToBlacklist(tokenId, expiresIn); | |
break; | |
case 'google': | |
// Add code to blacklist the Google token | |
break; | |
case 'github': | |
// Add code to blacklist the Github token | |
break; | |
default: | |
throw new BadRequestException('Invalid strategy'); | |
} | |
return { message: 'Logout successful' }; | |
} | |
} | |
npm install google-auth-library | |
import { OAuth2Client } from 'google-auth-library'; | |
constructor(private readonly configService: ConfigService) {} | |
const googleConfig = this.configService.get('google'); | |
const oAuth2Client = new OAuth2Client( | |
googleConfig.clientId, | |
googleConfig.clientSecret, | |
googleConfig.redirectUri, | |
); | |
async revokeGoogleToken(token: string) { | |
await oAuth2Client.revokeToken(token); | |
} | |
await this.revokeGoogleToken(req.user.accessToken); | |
req.logout(); | |
return { message: 'Logout successful' }; | |
import { Controller, Post, Req, UseGuards } from '@nestjs/common'; | |
import { AuthGuard } from '@nestjs/passport'; | |
import { ConfigService } from '@nestjs/config'; | |
import { OAuth2Client } from 'google-auth-library'; | |
@Controller('auth') | |
export class AuthController { | |
constructor(private readonly configService: ConfigService) {} | |
@Post('logout') | |
@UseGuards(AuthGuard('jwt'), AuthGuard('google'), AuthGuard('github')) | |
async logout(@Req() req: any) { | |
if (req.user.provider === 'google') { | |
await this.revokeGoogleToken(req.user.accessToken); | |
} | |
req.logout(); | |
return { message: 'Logout successful' }; | |
} | |
private async revokeGoogleToken(token: string) { | |
const googleConfig = this.configService.get('google'); | |
const oAuth2Client = new OAuth2Client( | |
googleConfig.clientId, | |
googleConfig.clientSecret, | |
googleConfig.redirectUri, | |
); | |
await oAuth2Client.revokeToken(token); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment