Open seohl16 opened 2 years ago
새로운 프로젝트를 nest 언어로 만든다
nest new kakao-oauth-study
nest g module auth && nest g controller auth --no-spec && nest g service auth --no-spec
kakao passport 관련 필요한 모듈 설치한다.
npm install @nestjs/passport passport passport-kakao @types/passport-kakao --save
config 파일을 쓰기 위한 모듈을 설치한다.
npm install config --save
src랑 같은 루트에 config 이름의 폴더를 만든다. default.yaml 파일을 만들어서 다음과 같이 카카오 api를 쓰기 위한 정보를 기입한다.
kakao:
clientId: 'bfa473f3e7sdw2abe14f' // RESTAPI 키
callbackURL: 'http://localhost:3000/auth/kakao/redirect'
원래 production, development 등 세부로 나누어야 하는데 여기서는 간단하게 기본 yaml파일만 사용
.
auth 폴더 안에 dto 폴더를 만들고 auth.kakao-dto.ts 파일을 만든다.
export class AuthKakaoDto {
name: string;
kakaoid: string;
}
아까 동의했던 닉네임과 카카오 아이디를 받겠다고 명시한다.
import { Injectable } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-kakao";
import * as config from 'config';
import { AuthKakaoDto } from "./dto/auth.kakao-dto";
@Injectable()
export class StrategyKakao extends PassportStrategy(Strategy, 'kakao') {
constructor() {
super({
clientID: config.get('kakao.clientId'),
callbackURL: config.get('kakao.callbackURL'),
});
}
async validate(accessToken: string, refreshToken: string, profile, done) {
console.log(accessToken); # 확인용
const payload: AuthKakaoDto = {
name: profile._json.kakao_account.profile.nickname,
kakaoid: profile._json.id,
};
done(null, payload);
}
}
kakao API에서 token을 돌려주면서 redirectURL로 이동하는데 이때 validate 함수를 거치고 controller로 이동하게 된다.
src
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── auth
│ ├── auth.controller.ts
│ ├── auth.module.ts
│ ├── auth.service.ts
│ ├── dto
│ │ └── auth.kakao-dto.ts
│ └── kakao.strategy.ts
└── main.ts
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { StrategyKakao } from './kakao.strategy';
@Module({
controllers: [AuthController],
providers: [AuthService, StrategyKakao]
})
export class AuthModule {}
providers에 아까 만든 StrategyKakao 를 추가한다.
import { Controller, Get, HttpCode, HttpStatus, Req, Res, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { AuthService } from './auth.service';
@Controller('auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@Get('/kakao')
@HttpCode(200)
@UseGuards(AuthGuard('kakao'))
async kakaoLogin() {
return HttpStatus.OK;
}
@Get('/kakao/redirect')
@HttpCode(200)
@UseGuards(AuthGuard('kakao'))
async kakaoLoginCallback(@Req() req, @Res() res) {
console.log(req.user, req.query);
console.log('finish');
res.redirect('http://localhost:3000')
}
}
controller를 수정한다. 사용자가 localhost:3000/auth/kakao에 접속하면 kakao API가 사용자 로그인을 요구한다. 로그인을 한 사용자가 이 앱을 허용하기로 하면 kakao는 accesstoken과 profile을 제공해준다. profile json에는 id, profile nickname 등이 있어서 정보를 받을 수 있다.
validate가 수행되고 나면 kakaoAPI에 설정해두었던 localhost:3000/auth/kakao/redirect가 정의된 controller 함수로 이동한다. kakaoLoginCallback 함수가 잘 되는지 확인하기 위해 console log를 찍어본 결과 req.user, req.query 등이 잘 뽑히는 것을 알 수 있다. 마지막으로 localhost:3000/로 이동시켜서 code= 등 param이 안 뜨게 url을 보인다.
API를 위한 설정
Kakao Developers에 어플리케이션 만들기
Kakao Developers라는 사이트에 접속한다. https://developers.kakao.com/
카카오 계정 로그인 후 내 어플리케이션에 들어간다.
카카오 로그인 설정하기