CORS Error (with. Kakao Social Login)

IRE_0546·2021년 8월 6일
2
post-thumbnail

Access to XMLHttpRequest at 'URL2 : Destination URL' from origin 'URL1 : Source URL (ex.http://localhost:3000)' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

저번에도 그렇고, 이번에도 그렇고 Kakao Social 로그인에 정말 삽질을 많이 했던 것 같다. 이번에는 이 오류를 겪으면서 알게 되었던 CORS 오류에 대해서 간략하게 기록을 남기고자 한다.

CORS 문제

이 문제를 알기 위해서 아래의 개념들을 알아 보는 것이 중요할 것 같아 정리를 해보았다.

동일 출처 정책 (same-origin policy)
: 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스 상호작용을 하는 것을 제한하는 중요한 보안 방식이다. 즉, 동일한 출처 간의 호출만 허용한다.

동일한 출처란? 두 URL의 프로토콜, 포트, 호스트가 모두 같은 경우를 말한다. 그럼 예를 들어, 5000번의 포트에서 개발을 하고 있다고 하면 5000번 포트, 프로토콜 호스트가 모두 같은 경우에만 허용한다는 것이다.

그래서 내가 5000번 로컬에서 작업을 하고 있다가 외부 서버의 API의 결과를 받으려고 해도 이 오류 때문에 안되는 것이었다.

크로스 도메인 (Cross Domain)
: 자바스크립트 (JavaScript)의 동일 출처 정책(same-origin-policy)에 어긋나는 호출을 말한다. 즉, 서로 다른 도메인 간의 호출이라는 것이다.

그래서 아까 말했듯이, 다른 도메인 서버의 데이터에 접근이 불가능한 문제가 생긴다. 그러나 카카오 로그인처럼 불가피하게 API 사용을 하거나 서버의 효율적 이용을 위해서는 이를 허용해야 한다.

문제 해결 방법

나는 이 문제를 React+Webpack+Redux 환경에서 해결하기 위해 다음과 같은 네 가지 방법을 사용했다. 결론적으로, 다른 URL은 아래의 방법들이 통했지만 카카오 소셜 로그인에 적용은 세 가지 방법이 다 안돼서 임시 방편으로 크롬의 보안을 다운하는 방법으로 개발을 진행하였다.

  1. React에서 middle-ware를 설치
  2. Webpack 설정에서 Package.json을 수정 (proxy)
  3. axios header 설정
  4. chrome 자체 설정

React http-proxy-middleware 설정 & axios header 설정

두 서버 간의 프록시 서버를 둠으로써 문제를 해결하는 첫 번째 방식을 사용해 보았다.

npm install http-proxy-middleware

/src/setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
    app.use(
        '/api',
        createProxyMiddleware({
            target: "https://kapi.kakao.com/v2/user/me",
            changeOrigin: true,
            pathRewrite: {
                '^/api': '' //url intialize
            }
        })
    )
}

axios를 사용한 부분

const getInformation = (accessToken) => {
    axios.get("https://kapi.kakao.com/v2/user/me", {
        headers: {
            //kakao server에서 설정해 주어야 한다 -> CORS 문제
            "Access-Control-Allow-Origin": "*",
            Authorization: `Bearer ${accessToken}`
        }
    }).then((data) => {
        console.log(data);
        //issue: Data -> json 형식으로 분리 요청
        //window.alert("get information success!")

    }).catch((error) => {
        console.log("get information failed", error);
        //window.alert("get information failed");

    });
};

여기서 코드를 보면 알 수 있겠지만, header 설정에 Access-Control-Allow-Origin 설정을 했음에도 불구하고 오류는 그대로였다. 그리고 middle ware를 설정했음에도 불구하고 주소가 자꾸 localhost:5000으로 잡혔다. 아마 proxy 설정이 제대로 먹히지 않은 듯 했다. 이유는 잘 모르겠다.

심지어 header에 설정하는 저 부분은 알고보니 Kakao 측에서 CORS를 허용해 주어야 한다는 것 같은데, 그럼 방도가 없었다. 그래서 다른 방법을 계속 시도해 보았다.

Webpack Package.json & Webpack.configure.js 설정 변경

우선 Package.json에 아래의 설정을 추가해 주었다.

package.json
proxy: "[허용할 주소]"

{
 "name": "ev-homage",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "proxy" : "https://kapi.kakao.com",
 ...
 }

그래도 안돼서 webpack.configure.js 설정을 추가했다. dev-server 설정을 추가해 주었다.

...
devServer: {
  headers: { 
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"
  },
  host: 'localhost',
  port: port,
  open: true, // open page when start
  historyApiFallback: true,
},
};
...

그래도 먹히지 않았다... 어떤 부분이 문제인지 생각하니 아무래도 Kakao API 자체의 문제인 것 같아서 아래의 방법으로 해결했다.

Chrome 자체 설정

--disable-web-security --user-data-dir="C:\chrome"

chrome 속성에 들어가서 위와 같이 경로에 추가를 하고, 바로가기로 크롬을 실행하면 된다. 그리고 프로젝트를 npm start해서 실행을 한 뒤에 서버가 실행되면 이전에 열었던 크롬으로 접속을 하면 코드가 동작한다. (CORS 오류 없이)

그래도 이 방법을 계속 사용할 수는 없는데... 다른 방법을 고민해야 한다.
찾아본 결과로는 JDK를 이용해서 하면 된다고 하는데, 그럼 REST API를 이용해서 하는 방식은 어떻게 해야할까? Proxy 서버를 만들어서 하는 방법이 있는데 어떻게 해야 할지는 고민을 해봐야겠다.

profile
Front-end developer, Time is flying never to return ✨

0개의 댓글