Bleeding edge

CORS 본문

CS

CORS

codevil 2022. 9. 1. 19:59

CORS란

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다

window.location.href

window객체의 location의 href를 들어가면, protocol, domain, port를 확인할 수 있다.이 세개가 모두 같을 때, 동일 출처란 이야기를 한다. 브라우저는 이 동일 출처 정책(Same-Origin Policy)라는 규칙을 가지고 있다.이 규칙은 브라우저를 거치지 않고 서버간 통신이아닌, 브라우저를 통해 서버에 요청을 할 때 적용된다.

CORS 해결 방법

Access-Control-Allow-Origin 응답 헤더 세팅
서버측 응답에서 접근 권한을 주는 헤더를 추가하여 해결

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
  res.header("Access-Control-Allow-Origin", "https://example.com"); // 특정 도메인
});

cors 모듈 사용

const cors = require("cors");
const app = express();

app.use(cors());

아무 옵션없이 설정하면 모든 cross-origin 요청에 대해 응답이므로, 특정 도메인이나 특정 요청에만 응답하게 옵션을 설정하는 것이 좋다.

특정 도메인 접근 허용

const options = {
  origin: "http://example.com", // 접근 권한을 부여하는 도메인
  credentials: true, // 응답 헤더에 Access-Control-Allow-Credentials 추가
  optionsSuccessStatus: 200, // 응답 상태 200으로 설정
};
app.use(cors(options));

특정 요청 접근 허용

app.get("/example/:id", cors(), function (req, res, next) {
  res.json({ msg: "example" });
});

webpack-dev-server proxy 기능
리액트 개발환경에서, 서버쪽 코드를 수정하지 않고 해결할 수도 있다. 아래와 같이 프록시 속성을 설정하면, 서버에서 해당 요청을 받아준다.

// 프록시 쓰지 않았을때
// localhost:8080(클라이언트 측) --X (CORS)--> domain.com (서버 측)

// 프록시를 설정 후
// localhost:8080(클라이언트 측) --O 프록시가 설정된 Webpack Dev Server--> domain.com (서버 측)

module.exports = {
  devServer: {
    proxy: {
      "/api": {
        target: "domain.com",
        changeOrigin: true,
      },
    },
  },
};

중간의 프록시 서버 덕분에, domain.com 서버에서는 같은 도메인(domain.com)에서 온 요청으로 인식하여 CORS 에러가 발생하지 않는다.

package.json에 proxy값을 설정
create-react-app 으로 생성한 프로젝트에서는, package.json 에 proxy 값을 설정하여 proxy 기능을 활성화 하는 방법도 있다.

{
    //...
    "proxy": "http://localhost:4000"
}