본문 바로가기

개발에 도움이 되는/Network

SOP(Same-Origin Policy), CORS(Cross-Origin Resource Sharing)

 

1. SOP (Same-Origin Policy) : 동일 출처 정책을 뜻하며, MDN에선 다음과 같이 정의한다.

어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식

정리하자면 "같은 출처의 리소스만 공유가 가능하다" 라는 정책이다.

 

 - 출처 (Origin) : Protocol, Host, Port의 조합으로 되어있다.

 ex) https://help-solomon.tistory.com:443/ 
 https = Protocol , help-solomon.tistory.com = Host, 443 = Port

 이 중 하나라도 다르면 동일한 출처로 보지 않는다.

 

SOP가 있어서 다른 사이트와의 리소스 공유를 제한하기 때문에 사용자 정보(ex. Login 정보)가 타 사이트의 코드에 의해 유출되는 것을 원천적으로 막을 수 있다.

 

하지만 개발을 하다보면 다른 출처의 리소스를 사용해야 하는 상황은 정말 많기 때문에 동일 출처 정책을 피하는 방법을 사용해야 한다. 그것이 바로 CORS이다. (CORS는 Error가 아니라 오히려 도와주는 역할)

 

 

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

 

 - CORS 설정 : front-end와 back-end 둘 다 설정할 수 있다.

 

   1) back-end

   - 응답 header에 설정

app.use((req, res, next) => {
// 모든 도메인
  res.header("Access-Control-Allow-Origin", "*"); 
  
// 특정 도메인
  res.header("Access-Control-Allow-Origin", "https://help-solomon.tistory.com");
  
//인증 정보를 포함한 요청을 받을 경우
	res.header("Access-Control-Allow-Credentials",  true);
});

 

   - Express 서버에서는 cors middleware를 사용해서 설정

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

//모든 도메인 허용
app.use(cors());

//특정 도메인 허용
const options = {
  origin: "https://help-solomon.tistory.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" });
});

 

   2) front-end

      - proxy를 이용하여 설정

      SOP 문제는 브라우저를 통과하며 발생하기 때문에 서버끼리의 통신에서는 발생하지 않는다. 

      그래서 front-end 단 웹서버에서 요청을 proxy 형태로 감싸 back-end 서버로 요청할 경우 Error가 발생하지 않는다.

   

      http-proxy-middleware를 이용하여 해결 ( axios와 사용 )

 

  • 설치
npm i http-proxy-middleware

 

  • root 경로에 setupProxy.js를 만듦
const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function (app) {
  app.use(
    "/api",
    createProxyMiddleware({
      target: "서버 URL",
      changeOrigin: true,
      pathRewrite: {
        "^/api": "",
      }
    })
  );
};

 

  • axios create
import axios from "axios";

export const api = axios.create({
  baseURL: "/api",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "", // 인증 key가 필요하다면 이런 식으로 header에 추가 가능
  },
});

 

반응형

'개발에 도움이 되는 > Network' 카테고리의 다른 글

HTTP Status Code  (0) 2022.04.05
WebSocket  (0) 2022.01.18
DNS(Domain Name System)  (0) 2022.01.14
OSI 7 계층(OSI 7 Layer)  (0) 2022.01.13
쿠키(Cookie), 세션(Session)  (0) 2022.01.11