diff --git a/src/auth/dtos/kakao-login.dto.ts b/src/auth/dtos/kakao-login.dto.ts new file mode 100644 index 0000000..c82c64d --- /dev/null +++ b/src/auth/dtos/kakao-login.dto.ts @@ -0,0 +1,3 @@ +import { CreateOAuthDto } from './oauth-login.dto'; + +export class KakaoLoginDto extends CreateOAuthDto {} diff --git a/src/auth/dtos/oauth-login.dto.ts b/src/auth/dtos/oauth-login.dto.ts new file mode 100644 index 0000000..ee51abf --- /dev/null +++ b/src/auth/dtos/oauth-login.dto.ts @@ -0,0 +1,3 @@ +export class CreateOAuthDto { + authorizationToken: string; +} diff --git a/src/auth/dtos/request/kakao-login.request.dto.ts b/src/auth/dtos/request/kakao-login.request.dto.ts new file mode 100644 index 0000000..7862673 --- /dev/null +++ b/src/auth/dtos/request/kakao-login.request.dto.ts @@ -0,0 +1,3 @@ +import { OAuthLoginRequest } from './oauth-login.request.dto'; + +export class KakaoLoginRequest extends OAuthLoginRequest {} diff --git a/src/auth/dtos/request/oauth-login.request.dto.ts b/src/auth/dtos/request/oauth-login.request.dto.ts new file mode 100644 index 0000000..ebaeced --- /dev/null +++ b/src/auth/dtos/request/oauth-login.request.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class OAuthLoginRequest { + @ApiProperty({ + description: 'OAuth 인증 토큰(ex. kakao access token, google id token)', + }) + authorizationToken: string; +} diff --git a/src/auth/oauth.controller.ts b/src/auth/oauth.controller.ts index faf6015..4507cca 100644 --- a/src/auth/oauth.controller.ts +++ b/src/auth/oauth.controller.ts @@ -22,6 +22,7 @@ import { OAuthService } from './oauth.service'; import { googleUserInfo } from './dtos/google.dto'; import { LoginOutput } from './dtos/login.dto'; import { ErrorOutput } from '../common/dtos/output.dto'; +import { KakaoLoginRequest } from './dtos/request/kakao-login.request.dto'; @Controller('oauth') @ApiTags('OAuth') @@ -129,4 +130,13 @@ export class OAuthController { async appleLogin(@Query('code') code: string): Promise { return this.oauthService.appleLogin(code); } + + @ApiOperation({ + summary: '카카오 로그인 요청', + description: 'accessToken을 받아 카카오 로그인을 요청합니다.', + }) + @Post('kakao') + async createOneWithKakao(@Body() kakaoLoginRequest: KakaoLoginRequest) { + return this.oauthService.createOneWithKakao(kakaoLoginRequest); + } } diff --git a/src/auth/oauth.service.ts b/src/auth/oauth.service.ts index c4275de..4d7b33c 100644 --- a/src/auth/oauth.service.ts +++ b/src/auth/oauth.service.ts @@ -19,6 +19,8 @@ import * as CryptoJS from 'crypto-js'; import { CookieOptions } from 'express'; import { RedisService } from '../infra/redis/redis.service'; import { REFRESH_TOKEN_KEY } from './constants'; +import { KakaoLoginRequest } from './dtos/request/kakao-login.request.dto'; +import { KakaoLoginDto } from './dtos/kakao-login.dto'; @Injectable() export class OAuthService { @@ -118,6 +120,40 @@ export class OAuthService { } } + async createOneWithKakao({ authorizationToken }: KakaoLoginDto) { + try { + const { userInfo } = await this.oauthUtil.getKakaoUserInfo( + authorizationToken, + ); + + const email = userInfo.kakao_account.email; + if (!email) { + throw new BadRequestException('Please Agree to share your email'); + } + + let user = await this.userRepository.findOneByEmail(email); + + // 회원가입인 경우 기본 카테고리 생성 작업 진행 + if (!user) { + user = new User(); + user.email = email; + user.name = userInfo.kakao_account.profile.nickname; + user.profileImage = userInfo.kakao_account.profile?.profile_image_url; + user.password = this.encodePasswordFromEmail( + email, + process.env.KAKAO_JS_KEY, + ); + + await this.userRepository.createOne(user); + await this.categoryRepository.createDefaultCategories(user); + } + + return this.oauthLogin(user.email); + } catch (e) { + throw e; + } + } + // Login with Google account info async googleOauth({ email,