[Codestates] Proxy

송현우·2022년 12월 8일
0
post-thumbnail

CORS - 교차 출처 리소스 공유

  • 웹 브라우저는 XMLHttpRequest, Fetch API 또는 <script> 등에 SOP를 따른다.
  • 때문에 CORS(Cross-Origin Resource Sharing)라는 추가적인 HTTP 헤더를 통해 다른 출처의 리소스에 접근할 권한을 부여해야 한다.
  • CORS 정책에 따라 올바른 요청을 보내면 Same-Origin이 아니더라도 통신할 수 있다.
  • 이러한 통신 제한 없이 운영된다면 누구나 리소스에 접근 가능하여 개인정보 탈취 등 악용당할 여지가 있다.
  • SOP(Same-Origin Policy)는 같은 출처의 리소스만 공유가 가능하다는 정책이다.
  • 다른 출처의 문서, 스크립트 등의 리소스와 상호작용하는 것을 막는다.
  • 여기서 출처란 프로토콜, 호스트, 포트의 조합으로, 이 중 하나라도 다르면 동일한 출처로 보지 않는다.
  • 올바른 CORS 요청의 방법은 3가지가 있다.

1. 프리플라이트 요청 (Preflight Request)

  • 실제 요청을 보내기 전, OPTIONS 메서드로 사전 요청을 보내 해당 출처에 접근 권한이 있는지부터 확인
  • 요청을 보낸 출처가 접근 권한이 없다면 브라우저에서 CORS 에러를 출력 및 요청 미처리
  • CORS에 대한 조치가 없음에도 프리 플라이트 요청을 통해 먼저 접근 권한을 확인한다면 CORS 에러

2. 단순 요청 (Simple Request)

  • 단순 요청은 특정 조건이 만족되면 프리플라이트 요청을 생략
  • GET, HEAD, POST 요청 중 하나여야 하며, Accept, Accept-Language, Content-Language, Content-Type 헤더의 값만 수동으로 설정 가능
  • Content-Type 헤더에는 application/x-www-form-urlencoded, multipart/form-data, text/plain 값만 허용

3. 인증정보를 포함한 요청 (Credentialed Request)

  • 요청 헤더에 인증 정보를 담아 출처가 다를 경우에는 별도의 설정을 하지 않으면 쿠키를 보낼 수 없음
  • 이 경우에는 프론트, 서버 양측 모두 CORS 설정이 필요
    프론트 측 요청 헤더 withCredentials : true
    서버 측 응답 헤더 Access-Control-Allow-Credentials : true
    서버 측에서 Access-Control-Allow-Origin 을 설정할 때, 모든 출처를 허용한다는 뜻의 와일드카드(*)로 설정하면 에러가 발생한다. 정확한 출처를 적는다.

  • 위와 같은 에러는 CORS 정책에 위반된 요청을 보냈기 때문에 발생한다.

  • 요청 헤더는 Origin 필드에 출처를 담아 보내며, 서버는 응답헤더의 Access-Control-Allow-Origin 필드에 허용할 출처를 담아 보낸다.
  • 브라우저는 이것을 통해 통신 가능 여부를 결정한다.
  • 위의 오류는 올바른 헤더를 설정하지 않았기 때문이다. 해결하기 위해서 Access-Control-Allow-Origin 필드를 재설정 해야 한다.

Proxy

  • 좌측은 정석적인 통신 절차를 나타낸 그림이다.
  • React 라이브러리, 혹은 Webpack Dev Server에서 제공하는 proxy 기능을 사용하면 우측처럼 CORS 정책을 우회할 수 있다.

webpack dev server proxy

// package.json
  ...
  },
	"proxy" : "우회할 API 주소" // "http://localhost:3080/" 등등
}
  • webpack을 사용 중이라면 webpack dev server에서 proxy 기능을 제공받을 수 있다.
  • package.json에 프록시 기능을 추가해준다.
export async function getAllfetch() {
    const response = await fetch('우회할 api주소/params');
    .then(() => {
			...
		})
}

export async function getAllfetch() {
    const response = await fetch('/params');
    .then(() => {
			...
		})
}
  • 기존 fetch문의 url 주소를 아래와 같이 파라미터만 남겨준다.
  • 설치 후 위와 같은 에러를 만났다면 클라이언트를 껐다 켜준다.

React Proxy

  • webpack dev server 에서 제공하는 proxy는 전역적인 설정으로 종종 충분히 적용되지 않는 경우가 존재한다.
  • 그럴때 http-proxy-middleware로 수동설정 해줄 수 있다.
  • npm install http-proxy-middleware --save로 라이브러리를 받아준다.
  // src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api', //proxy가 필요한 path prameter를 입력
    createProxyMiddleware({
      target: 'http://localhost:5000', //타겟이 되는 api url를 입력
      changeOrigin: true, //대상 서버 구성에 따라 호스트 헤더가 변경되도록 설정하는 부분
    })
  );
};
  • src폴더에 setupProxy.js를 생성하고 위와같이 설정해준다.
  • webpack dev server를 사용했을 때 처럼 fetch문의 url에 파라미터만 남겨준다.

0개의 댓글