카카오 로그인 serializer 구현
569
작성한 질문수 6
안녕하세요 제로초님.
passport-kakao를 이용해서 kakao 로그인을 구현해보고 있습니다.
로그인과 회원가입 까지는 잘 되는데, serializer을 통해서 cookie가 저장되지 않습니다.
kakako.strategy.ts
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-kakao';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as _ from 'lodash';
import { AuthService } from './auth.service';
import { Platform } from 'src/entities/common/Platforms';
@Injectable()
export class KakaoStrategy extends PassportStrategy(Strategy) {
constructor(
private readonly configService: ConfigService,
private authService: AuthService,
) {
super({
clientID: configService.get<string>('KAKAO_REST_API_KEY'),
clientSecret: configService.get<string>('KAKAO_CLIENT_SECRET'),
callbackURL: configService.get<string>('KAKAO_REDIRECT_URI'),
});
}
async validate(accessToken, refreshToken, profile, done) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {
_json: {
id,
properties: { nickname, profile_image: profileImage },
kakao_account: { email },
},
} = profile;
const user = await this.authService.findOrCreateUser(
email,
nickname,
Platform.KAKAO,
);
return done(null, user);
}
}
아래에 있는 kakao-auth.guard.ts와 kakao.serializer.ts는 로컬 로그인과 다른 점이 없을 것 같아서 그대로 썼습니다.
kakao-auth.guard.ts
import { ExecutionContext, Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class KakaoAuthGuard extends AuthGuard('kakao') {
async canActivate(context: ExecutionContext): Promise<boolean> {
const can = await super.canActivate(context);
if (can) {
const request = context.switchToHttp().getRequest();
await super.logIn(request);
}
return true;
}
}
kakao.serializer.ts
import { Injectable } from '@nestjs/common';
import { PassportSerializer } from '@nestjs/passport';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { AuthService } from './auth.service';
import { Users } from 'src/entities/Users';
@Injectable()
export class KakaoSerializer extends PassportSerializer {
constructor(
private readonly authService: AuthService,
@InjectRepository(Users) private usersRepository: Repository<Users>,
) {
super();
}
serializeUser(user: Users, done: CallableFunction) {
done(null, user.id);
}
async deserializeUser(userId: string, done: CallableFunction) {
return await this.usersRepository
.findOneOrFail({
where: { id: +userId },
select: ['id', 'email', 'nickname'],
})
.then((user) => {
done(null, user);
})
.catch((error) => done(error));
}
}이처럼 작성하면, 로그인 시 세션에 쿠키가 저장되어야 하는게 아닌가요?
사실 강의에서 설명해주신 내용중 이해가 잘 가지 않는 부분이 있습니다.
localStrategy에서 done(null, user) -> local-auth.guard.ts에서 super.logIn(request) -> local serializer 에서 serializeUser() 을 호출한다고 말씀하셨는데,
세 가지 파일에서 LocalStrategy, LocalAuthGuard, LocalSerializer을 서로 명시적으로 연결해준적이 없음에도 불구하고 어떻게 서로 잘 알아서 호출되는지 궁금합니다.
그냥 앞에 모두 Local이 붙어서, 잘 찾아서 호출되는 건가요?
답변 1
0
일단 카카오시리얼라이저를 따로 두실 필요 없고 로컬 시리얼라이저로 공용으로 쓸 수 있습니다. 코드로는 컨트롤러랑 모듈쪽도 같이 봐야할 것 같습니다.
@nestjs/passport 내부적으로 처리해주는 것이라 명시적인 연결 관계가 없습니다. express+passport에서도 이 때문에 헷갈리는 부분입니다.
0
authModule은 그냥 provider에 다 집어넣었습니다.
authController를 따로 만들지 않았고, 그냥 userController에 로컬로그인 + 카카오로그인 모두 처리했습니다
user.controller.ts
import {
Body,
Controller,
Get,
Post,
Req,
Res,
UseGuards,
} from '@nestjs/common';
import { JoinRequestDto } from 'src/dto/join.request.dto';
import { UsersService } from './users.service';
import { User } from 'src/decorators/user.decorator';
import { LocalAuthGuard } from 'src/auth/local-auth.guard';
import { AuthGuard } from '@nestjs/passport';
import { KakaoAuthGuard } from 'src/auth/kakao-auth.guard';
@Controller('api/users')
export class UsersController {
constructor(private userService: UsersService) {}
@Get()
getUsers(@User() user) {
return user;
}
@Post()
async postUsers(@Body() body: JoinRequestDto) {
await this.userService.postUsers(body.email, body.password, body.nickname);
}
@Post('login')
@UseGuards(LocalAuthGuard)
logIn(@Req() req) {
return req.user;
}
@Get('login/kakao')
@UseGuards(KakaoAuthGuard)
kakaoLogIn() {
return;
}
@Get('login/kakao/callback')
@UseGuards(KakaoAuthGuard)
kakaoLogInRedirect(@Req() req) {
return req.user;
}
@Post('logout')
logOut(@Req() req, @Res() res) {
req.logOut();
res.clearCookie('connect.sid', { httpOnly: true });
res.send('ok');
}
}로컬 시리얼라이저를 공용으로 사용하려면 어떻게 해야하나요?
0
카카오 시리얼라이저를 제거하고 로컬 시리얼라이저만 넣으면 됩니다. 로컬 시리얼라이저에서 로컬이라는 이름은 아무 역할도 하지 않습니다. 그냥 login 후에 req.user를 생성하는 시리얼라이저일 뿐입니다.
serializeUser랑 deserializeUser 안에 콘솔로그도 찍어보세요.
강의자료는 어디서 다운받나요?
0
114
4
질문 있습니다.
0
298
3
(강의 5:42 질문) providers를 통한 여러 개의 인스턴스 생성 & exports 통한 싱글톤 생성
0
154
2
코드 편집기 확장 프로그램
0
209
2
(질문)비밀 저장소에 접근하기 위한 인증 정보는 로컬 .env에 저장하는지?
0
143
2
(질문)외부 저장소를 통한 환경변수 불러오기 비동기 질문
0
168
3
로그인을 해도 LoggedInGuard쪽에서 false값이 나옵니다.
0
152
2
로그인방법이 고민됩니다.
0
190
2
yarn seed 명령어 실행 시 데이터 삽입 안됨
0
297
4
yarn run db:create 시에 발생하는 데코레이터 오류
0
242
2
npm run db:create 시에 발생하는 decorating 오류
0
232
2
RxJS 디버깅 질문 있습니다.
0
189
3
CacheManager에 대해 질문 있습니다.
0
174
2
로깅은 어떻게 하는게 효율적일까요?
0
224
1
CORS 질문 있습니다.
0
418
2
쿠키 옵션에 대해서 질문 있습니다.
0
184
2
로그아웃 요청이 403 forbidden 에러가 나는데 왜그런걸까요??
0
449
1
401 unauthorized문제
0
288
1
가드의 장점에 대해서 질문이 있습니다.
0
225
1
로그 관리에 대해 질문 있습니다.
0
252
2
CORS 에러 질문 있습니다.
0
319
2
배포 환경 DB 연결 질문 있습니다.
0
411
2
socket io 미 연결 문제 (nest & flutter)
1
1154
3
no elements in sequence 에러 관해서 질문이 있습니다.
0
454
1





