인프런 커뮤니티 질문&답변
nestjs google login (섹션30과제) 질문
해결된 질문
작성
·
684
·
수정됨
0
선생님 안녕하세요.
구글 소셜로그인 기능에 대해서 과제를 진행하고 있었는데요.
과제 영상에 따라서 따라 내려가고있었는데 nestjs로 REST API를 생성하는데 있어서 refreshToken을 발급해줘야하는 단계에서 res가 에러가 발생합니다.
IAuthServiceRefreshToken의 인터페이스에서 res가 없다는 것으로 확인이되는것 같은데요.
이전에 context로 graphql의 인터페이스를 사용해주었었는데
context를 없애고
req로 변경하고 Express의 Response를 생성해주면 REST API가 되는걸까요?!
이전까지 진행했을때는 Icontext를 생성해서 유저를 찾아내는 방식이었는데 강의내용에는 이런게 빠져있어서 어떻게 해나가야 하는지 좀 헷갈리는것 같습니다.
참고내용으로 이전에 사용했던 소스코드들을 공유드려봅니다.
//auth.service.ts
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import {
IAuthServiceGetAccessToken,
IAuthServiceLogin,
IAuthServiceRestoreAccessToken,
IAuthServiceSetRefreshToken,
} from './interfaces/auth-service.interface';
@Injectable()
export class AuthService {
constructor(
private readonly userService: UsersService, //
private readonly jwtService: JwtService,
) {}
async login({ email, password, context }: IAuthServiceLogin) {
// 1. 이메일이 일치하는 유저를 DB에서 찾기
const user = await this.userService.findOneByEmail({ email });
// 2. 일치하는 유저가 없으면?! 에러 던지기!!!
if (!user)
throw new UnprocessableEntityException('존재하지 않는 이메일입니다.');
// 3. 일치하는 유저가 있지만, 비밀번호가 틀렸다면?!
const isAuth = await bcrypt.compare(password, user.password);
if (!isAuth) throw new UnprocessableEntityException('틀린 암호입니다.');
// 4. refreshToken(=JWT)을 만들어서 브라우저 쿠키에 저장해서 보내주기
this.setRefreshToken({ user, context });
// 5. 일치하는 유저도 있고, 비밀번호도 맞았다면?!
// => accessToken(=JWT)을 만들어서 브라우저에 전달하기
return this.getAccessToken({ user });
}
getAccessToken({ user }: IAuthServiceGetAccessToken): string {
return this.jwtService.sign(
{ sub: user.id },
{
secret: process.env.JWT_SECRET_KEY,
expiresIn: process.env.JWT_ACCESS_TOKEN_EXPIRE,
},
);
}
setRefreshToken({ user, context }: IAuthServiceSetRefreshToken): void {
const refreshToken = this.jwtService.sign(
{ sub: user.id },
{
secret: process.env.JWT_REFRESH_SECRET_KEY,
expiresIn: process.env.JWT_REFRESH_TOKEN_EXPIRE,
},
);
//개발환경
context.res.setHeader(
'set-Cookie',
`lovely soong=${refreshToken}; path=/;`,
);
// 배포환경
// context.res.setHeader('set-Cookie', `refreshToken=${refreshToken}; path=/; domain=.mybacksite.com; SameSite=None; Secure; httpOnly`);
// context.res.setHeader('Access-Control-Allow-Origin', 'https://myfrontsite.com');
}
restoreAccessToken({ user }: IAuthServiceRestoreAccessToken): string {
return this.getAccessToken({ user });
}
}
확인부탁드리겠습니다 감사합니다.
답변 2
0
안녕하세요! zeler1004님!
해당 타입스크립트 에러 메시지를 읽어보니 IAuthServiceSetRefreshToken에 res를 받을 수 없도록 되어있다고 한 것 같아요!
현재 넘어가는 res는 Response 타입으로 잘 되어있는 것 같은데, 반대로 받는 부분(IAuthServiceSetRefreshToken이 들어가는 setRefreshToken 함수)에서는 res를 받는 타입이 아직 설정되지 않았네요!
따라서, IAuthServiceSetRefreshToken에서 res를 받을 수 있도록 변경해 주세요!^^
네! 코드에는 정답이 없기 때문에, 가장 효율적인 방법을 취해주시면 좋을 것 같아요!
크게 2가지 방법이 있을 것 같네요!
기존의 interface에 res도 추가하기
기존에 받고 있던 context를 res만 받도록 변경하고, res로 통합하기
음! 가급적 아래 2번을 추천드려요!
0
안녕하세요, 인프런 AI 인턴입니다.
질문 내용을 보니 refreshToken 발급하는 부분에서 res에 대한 에러가 발생하는 것 같습니다.
REST API에서도 req, res 객체를 사용할 수 있습니다. 하지만 GraphQL과는 다르게 context 객체를 사용하지 않으므로 req, res 객체를 직접 사용할 수 있습니다.
제 코드분석을 하기 위해서는 완전한 코드가 필요합니다. 현재는 authService 부분만 올려주셨는데, 해당 파일 외에 다른 파일들도 에러가 발생한 부분이 있을 수 있습니다.
코드를 분석하기 전에, 에러 코드와 함께 전체 코드를 첨부하거나 에러 코드와 함께 상세한 내용을 알려주시면 더욱 정확한 대답을 드릴 수 있을 것 같습니다.
감사합니다.






선생님 그럼 IAuthServiceSetRefreshToken 의 interface에서 res를 받을 수 있도록 설정한다면 이전에 graphql을 활용해서 진행했던 소스코드들과 사용할때의 interface와 다르다보니 그 graphql을 사용하지 않고 REST API만을 활용하기 위해서 이 기능만 살려놓는 interface를 사용해야한다는 걸로 이해되는데 맞을까요?(제가 설명이 좀 잘 못하는것 같은데... 쉽게 표현한다면.. 결국 REST API를 위한 interface를 만들어야 하는것이니 res를 받을 수 있도록 하고자 한다면 이전에 IAuthServiceSetRefreshToken을 사용했던 타입들은 못쓰게 되는거겠죠?!)
아직 부족하게 배우고 있는것 같아서 설명이 좀 빈약한것 같습니다 죄송합니다 ㅠㅜ..