• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

프론트에서 credentials: include로 설정한경우 cors 문제

23.06.06 18:53 작성 23.06.06 18:55 수정 조회수 1.61k

0

안녕하세요.

프론트와 백엔드 통신 중에 문제가 있어 질문드립니다.

restoreAcessToken 기능을 사용하기 위해서 쿠키를 사용해야 합니다.
서버측과 프론트측 주소가 다른 경우 쿠키 정보를 전송하기 위해서는

credentials: 'include'로 설정해야 하잖아요?

그러면 브라우저에 다음과 같은 오류가 발생합니다.
Access to fetch at 'http://localhost:3000/graphql' from origin 'http://localhost:8080' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

프론트 주소: localhost:8080

백엔드 주소: localhost:3000

서버측에서 cors 문제를 해결하기 위해 사용한 코드는 아래와 같습니다.

app.enableCors({
        origin: "http://localhost:8080", // 요청을 보내는 클라이언트의 주소를 명시
        credentials: true,
    });

오류 해결을 위해서 어떻게 해야하는 걸까요? 

 

그리고 새 토큰을 발급 받는 아래 setRefreshToken의 코드도 수정돼야 하는지요? network 탭에서는 쿠키가 들어온게 확인이 되는데 application 탭에서는 확인이 됐다 안됐다 합니다..

setRefreshToken({ user, res }: IAuthServiceSetRefreshToken): void {
        const refreshToken = this.jwtService.sign({ email: user.email, sub: user.userId }, { secret: process.env.JWT_REFRESH_KEY, expiresIn: "2w" });

        res.setHeader("Set-Cookie", `refreshToken=${refreshToken}; path=/;`);
    }

 

답변 부탁드립니다.

감사합니다.

답변 1

답변을 작성해보세요.

0

안녕하세요! Haewoong님!
실제로 프론트엔드를 구성하여 실습을 하고 계신 것 같네요!
질문을 보니, 실력이 점점 성장하시는 게 눈으로 보이네요!^^

우리가 백엔드에서 refreshToken 수업을 진행하는 동안에는 아무런 문제 없이! cookie에 들어있는 refreshToken이 정상적으로 담겨서 api에 보내졌습니다.
이 이유는 CORS 문제가 발생하지 않았기 때문이에요!
무슨 뜻인가...?

  • 브라우저: (playground주소 => http://localhost:4000)

  • 백엔드서버: http://localhost:4000/graphql

    따라서, 도메인과 포트가 동일(CORS 환경이 아닌 상태)하므로 refreshToken을 쉽게 브라우저와 백엔드 사이에서 주고 받는 것이 가능했답니다!

그렇다면, 도메인과 포트가 다른(CORS 환경인 상태)에서는 어떻게 해야 할까요?!
2가지 문제를 해결하셔야 합니다!

1. cors 허용!
=> 이 부분은 이미 설정 하신 것 같네요!

  1. credentials 허용!
    => 이 부분도 이미 설정 하신 것 같네요!

    따라서, 설정이 제대로 되어 있는 것 같아요!
    헌데, 에러 메시지를 보니 다른 설정으로 시도하신 에러 메시지가 아닌가 싶어요!
    보여주신 에러 메시지는 origin: "*" (모두허용) 이 들어있을 때 발생하는 에러 메시지랍니다!
    보안목적상 쿠키를 모든 origin에 대해서 허용할 순 없어요!
    동일한 예제 스크린샷을 보내드립니다.
    image

따라서, origin을 다시 제대로 설정하셔서 시도해 보시기 바랍니다!
아래는 정상적인 상황에서의 실행 결과입니다!
imageimage
또한, 아래는 위 상황에서 추가된 refreshToken 쿠키에요
image

 

강사님 확인 결과 Apollo 서버를 사용하는 경우에는 app.module에서 아래의 설정을 해주어야 합니다.

GraphQLModule.forRoot<ApolloDriverConfig>({
            cors: {
                origin: "http://localhost:8080", // 요청을 보내는 클라이언트의 주소를 명시
                credentials: true,
            },
        }),

Apollo 서버를 사용하는 경우 Apollo 서버에서 자체적인 cors 정책을 가지고 있고 해당 정책이 graphQL 통신을 사용할 때는 더 우선한다고 합니다. 따라서 위의 정책이 우선하여 적용되게 됩니다. 안해주면 nestJS에서 cors 설정해줘도 graphQL 통신시 오류가 나게 되구요.

몇일을 헤맸는데 겨우 찾았네요;; 휴..

Haewoong님!
결국 해내셨군요! Haewoong님의 열정에 박수를 보내드립니다! ㅎㅎ

사실, 위에 답변드린 코드는 실제로 정상 작동되는 코드를 스크린 샷으로 찍은 것이었어요!

Haewoong님의 답변을 보고 어디에서 차이가 나는지 원인을 찾아보니, 버전이 달라지면서 GraphQLModule의 cors 옵션에 변경사항이 생긴 것 같아요!

아래는 제가 가지고 있는 버전의 GraphQLModule("nestjs/apollo": "11.0.4", "nestjs/graphql": "11.0.4") 입니다!
여기에는 cors가 존재하지 않네요! ㅜㅜ

image버전이 업데이트 되면서 변경 사항이 생긴 것 같아요!!

도움이 되지 못해 아쉽지만 스스로 해결하신 Haewoong님을 보니 감동이에요! ㅎㅎ
해결 방법에 대해 공유해주셔서 감사합니다!

그렇군요. 개발을 하다보니 묘듈 버전에 따른 이슈가 상당히 많은 것 같네요. 버전에 따른 모듈간 호환성 문제도 있고. 앞으로 오류나면 이 부분부터 의심을 해봐야 겠네요.