사실 두개의 코드가 같아서 하나만 해결하면 다른 로그인은 쉽다.
//구글 oauth
npm i @nestjs/passport passport passport-google-oauth20
//카카오 oauth
npm i @nestjs/passport passport passport-kakao @types/passport-kakao
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthController } from './auth/auth.controller';
import { AuthModule } from './auth/auth.module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot(), AuthModule],
controllers: [AppController, AuthController],
providers: [AppService],
})
export class AppModule {}
import { Controller, Get, UseGuards, Res, Req } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Controller('auth')
export class AuthController {
/* 구글 */
@Get('google')
@UseGuards(AuthGuard('google'))
async googleLogin() { }
@Get('google/callback')
@UseGuards(AuthGuard('google'))
async googleLoginCallback(@Req() req, @Res() res) {
const jwt: string = req.user.jwt;
if (jwt) res.redirect('http://localhost:3005/login/success/' + jwt);
else res.redirect('http://localhost:3005/login/failure');
}
// google 에서 kakao로만 수정됐을뿐 달라진건 없다.
/* 카카오 */
@Get('kakao')
@UseGuards(AuthGuard('kakao'))
async kakaoLogin() { }
@Get('kakao/callback')
@UseGuards(AuthGuard('kakao'))
async kakaoLoginCallback(@Req() req, @Res() res) {
const jwt: string = req.user.jwt;
if (jwt) res.redirect('http://localhost:3005/login/success/' + jwt);
else res.redirect('http://localhost:3005/login/failure');
}
// 얘는 하나만 있어도 되는 모양.
@Get('protected')
@UseGuards(AuthGuard('jwt'))
protectedResource() {
return 'JWT is working!';
}
}
//src/strategies/google.strategy.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-google-oauth20';
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor(private readonly configService: ConfigService) {
super({
clientID: configService.get('GOOGLE_CLIENT_ID'),
clientSecret: configService.get('GOOGLE_CLIENT_SECRET'),
callbackURL: configService.get('GOOGLE_CALLBACKURL'),
passReqToCallback: true,
scope: ['profile'], // 가져올 정보들
});
}
async validate(
request: any,
accessToken: string,
refreshToken: string,
profile,
done: any,
) {
try {
console.log(profile);
const jwt = 'placeholderJWT';
const user = {
jwt,
};
done(null, user);
} catch (err) {
console.error(err);
done(err, false);
}
}
}
//src/strategies/kakao.strategy.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { Profile, Strategy } from 'passport-kakao';
@Injectable()
export class KakaoStrategy extends PassportStrategy(Strategy) {
constructor(private readonly configService: ConfigService) {
super({
clientID: configService.get('KAKAO_CLIENT_ID'),
clientSecret: configService.get('KAKAO_CLIENT_SECRET'),
callbackURL: configService.get('KAKAO_CALLBACK_URL'),
});
}
async validate(
accessToken: string,
refreshToken: string,
profile: Profile,
done: (error: any, user?: any, info?: any) => void,
) {
try {
const jwt = 'placeholderJWT';
const user = {
jwt,
};
done(null, user);
} catch (error) {
done(error);
}
}
}
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { PassportModule } from '@nestjs/passport';
import { GoogleStrategy } from 'src/strategies/google.strategy';
import { ConfigModule } from '@nestjs/config';
import { KakaoStrategy } from 'src/strategies/kakao.strategy';
@Module({
imports: [PassportModule.register({ defaultStrategy: 'jwt' }), ConfigModule],
controllers: [AuthController],
providers: [GoogleStrategy, KakaoStrategy],
})
export class AuthModule { }
providers: [GoogleStrategy, KakaoStrategy]를 안넣어주면 Error: Unknown authentication strategy "google"가 발생한다.

참고 블로그
https://velog.io/@jinony/Nest.js%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-OAuth-2.0-%EA%B5%AC%ED%98%84
https://velog.io/@leemhoon00/Nestjs-JWT-%EC%9D%B8%EC%A6%9D-%EA%B5%AC%ED%98%84