Access to XMLHttpRequest at ... from origin ... has been blocked by CORS policy: Response to preflight request doesn't pass access control check:

Suxxzzy.log·2022년 3월 26일
0

에러핸들링

목록 보기
29/32

Oauth 스프린트 진행 중 마주한 cors에러이다.
이는 서버측에 auth code를 전달하기 위해 axios.post 요청에서
withcredentials: true 설정을 해 준 것 때문이었는데 좀 더 자세한 이유를 보고자 한다.(위의 cors 에러 때문에 아래의 post 요청도 에러가 나는 것을 확인할 수 있었다.
이런 에러는 이미지를 불러오는 요청이든, auth code를 서버에 보내는 요청이든 다 동일하게 발생하였다. )


에러 내용을 말 그대로 해석해보자
http://localhost:3000에서 http://localhost:8080/callback로 ajax요청을 보냈는데 금지되었다.
예비 요청에 대한 응답이 access control check 과정을 통과하지 못했다는 뜻이다.
응답 메세지에 있는 Access-control-allow-credentials 헤더가 지금은 아무것도 없는 빈 값이다('')

나는 요청을 보낼 때 withCredentials: true 라고 설정(=request의 credntials 모드가 include라는 뜻)을 해 주었는데,
이렇게 되면 Access-control-allow-credentials헤더의 값도 무조건 true여야,
클라이언트가 응답을 받아들인다. 그러므로, withCredentials: true 헤더를 제거하여야 한다.

또는 헤더를 그대로 두고, 공식문서에서 언급한대로 다음의 옵션을 주는 방법도 있다.

credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.

응답의 credentials 헤더 부분을 true로 설정한 게 없었기 때문에, 클라이언트 측에서는 응답 메세지의 Access-Control-Allow-Credentials헤더가 설정이 안되있네? 그럼 이 응답은 버려야지! 라고 에러를 출력하는 것이다.

진짜 되는지 확인하려고 아래와 같이 고쳤더니 진짜 해결됐다.

cors({ origin: true, credentials: true })

그럼 위의 에러메세지 중 request의 credntials 모드가 include라는 건 무슨 뜻인가?
fetch 메서드에서 credentials: include로 설정 시, 응답의 access-control-allow-origin의 값은 명시적인 url이어야 한다. 로 쓰면 안된다는 뜻이다.
실제로 withCredentials: true 설정해준 것 때문에 서버의 origin을 "
"로 설정하게 되면 에러가 났다.

현재 서버 측에는 cors 설정이 다음과 같이 되어 있었다.

app.use(
  cors({ origin: true })
);

origin이 true라는 건 뭔 말인가?
공식문서Configuration Options에서 발췌

origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:
Boolean - set origin to true to reflect the request origin, as defined by req.header('Origin'), or set it to false to disable CORS.

쉽게말해 origin은 Access-Control-Allow-Origin 헤더 설정하는 부분임
허용할 요청의 출처, 즉 어느 곳에서 들어올지를 정하는 옵션이다.
true로 설정하게 되면 요청을 하는 곳의 주소는 접근을 허용하겠다는 뜻이다.

...

다시 정리하는 cors 옵션 설정 방법 예시

cors({
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", //배열도 가능
  "preflightContinue": false,
  "optionsSuccessStatus": 204
})
profile
몫을 다하는 사람

0개의 댓글