NestJS 프로젝트에서 소셜 로그인 기능을 추가하는 방법을 안내합니다. 이 과정을 통해 사용자는 Google 계정을 이용하여 소셜 로그인을 할 수 있게 됩니다.
먼저 passport
와 Google OAuth 2.0을 사용하기 위한 passport-google-oauth20
패키지를 설치합니다. 타입스크립트 사용자의 경우, 해당 @type 패키지도 설치해야합니다.
npm install passport-google-oauth20
npm install --save @types/passport-google-oauth20
Google Cloud Platform(GCP)에서 OAuth 클라이언트 ID를 생성하기 위해 프로젝트를 만들어야 합니다. 다음 단계를 따라 프로젝트를 생성하세요
해당 사이트로 접속하여 구글 계정으로 로그인을 실시하고 우측 상단의 새 프로젝트를 생성해줍니다.
GCP Console에서 OAuth를 이용하기 위해서 프로젝트를 생성합니다.
OAuth 클라이언트 ID와 Secret을 발급받기 위해 다음과 같이 사용자 인증 정보를 설정합니다.
1. API 및 서비스 > 사용자 인증 정보로 이동합니다.
2. 사용자 인증 정보 만들기 버튼을 클릭한 후 OAuth 클라이언트 ID를 선택합니다.
위 단계를 완료하면, Google Cloud Platform에서 발급 받은 클라이언트 ID와 Secret을 이용하여 Passport Google Strategy를 설정하고, 소셜 로그인 기능을 구현할 수 있습니다.
import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { PassportStrategy } from '@nestjs/passport'
import { Profile, Strategy, VerifyCallback } from 'passport-google-oauth20'
import { User } from 'src/user/entities/user.entity'
import { UserService } from 'src/user/services/user.service'
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
constructor(
private configService: ConfigService,
private userService: UserService,
) {
super({
clientID: configService.get('GOOGLE_CLIENT_ID'),
clientSecret: configService.get('GOOGLE_CLIENT_SECRET'),
callbackURL: configService.get('GOOGLE_CALLBACK_URL'),
scope: ['email', 'profile'],
})
}
async validate(
accessToken: string,
refreshToken: string,
profile: Profile,
done: VerifyCallback,
) {
const { id, name, emails } = profile
const providerId = id
const email = emails[0].value
const user: User = await this.userService.findByEmailOrSave(
email,
name.familyName + name.givenName,
providerId,
)
done(null, user)
}
}
Strategy는 프로바이더이므로 AuthModule에 등록해야합니다.
import { Module } from '@nestjs/common'
import { AuthService } from './services/auth.service'
import { AuthController } from './controllers/auth.controller'
import { JwtModule } from '@nestjs/jwt'
import { PassportModule } from '@nestjs/passport'
import { JwtAccessTokenStrategy } from './strategy/jwt-access.strategy'
import { JwtRefreshTokenStrategy } from './strategy/jwt-refresh.strategy'
import { LocalStrategy } from './strategy/local.strategy'
import { UserModule } from 'src/user/user.module'
import { GoogleStrategy } from './strategy/google.strategy'
import { TypeOrmExModule } from 'src/common/decorator/typeorm-ex.module'
import { UserRepository } from 'src/user/user.repository'
@Module({
imports: [
UserModule,
PassportModule.register({ defaultStrategy: 'jwt', session: false }), // 세션 쿠키를 사용하지 않는다.
TypeOrmExModule.forCustomRepository([UserRepository]),
JwtModule.register({}),
],
controllers: [AuthController],
providers: [
AuthService,
LocalStrategy,
GoogleStrategy,
JwtAccessTokenStrategy,
JwtRefreshTokenStrategy,
],
})
export class AuthModule {}
이 가드는 컨트롤러에서 Google 계정으로 로그인해야 하는 경로를 보호하는 데 사용될 수 있습니다. Google 자격증명을 사용하여 로그인할 수 있는 경로가 있을 때, 이 가드는 인증 과정이 설정한 전략에 따라 처리되도록 합니다.
import { Injectable } from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
@Injectable()
export class GoogleAuthGuard extends AuthGuard('google') {}
import { Controller, Get, Req } from '@nestjs/common'
import { AuthService } from '../services/auth.service'
import { UseGuards } from '@nestjs/common'
import { CurrentUser } from '../../common/decorator/current-user.decorator'
import { User } from 'src/user/entities/user.entity'
import { GoogleAuthGuard } from '../guard/google.guard'
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
// 생략
@Get('/google/login')
@UseGuards(GoogleAuthGuard)
async googleAuth(@Req() req) {
console.log('GET google/login')
}
@Get('/google/callback')
@UseGuards(GoogleAuthGuard)
async googleAuthRedirect(@CurrentUser() user: User): Promise<User> {
return user
}
'/google/login'은 로그인할 경로이고, '/google/callback'은 로그인 후 다시 해당 페이지로 연결해주는 경로입니다.
터미널에서 npm run start:dev로 서버를 실행합니다. 서버가 실행되었으면 http://localhost:3000/auth/google/login
에 접속합니다.
데이터베이스에 유저가 잘 생성된것을 확인할 수 있습니다.
위 과정을 통해 구현한 NestJS의 Google OAuth 로그인 기능은 사용자가 Google 계정으로 간편하게 로그인할 수 있게 해줍니다. 모듈화된 구조 덕분에 다른 소셜 로그인 기능도 유사한 방식으로 쉽게 추가할 수 있습니다.
이 글이 NestJS를 사용하여 Google 로그인 기능을 구현하는 데 도움이 되길 바랍니다. 필요한 모든 설정과 코드가 포함되어 있으며, 추가적인 구현에 필요한 서비스 로직은 프로젝트의 요구사항에 따라 자유롭게 추가하시면 됩니다.