
기술 면접을 대비해 개념을 🍰 한입 크기로 잘라 정리합니다.
깃허브가 궁금하다면 놀러오세요!
👉 깃허브 보러가기 (Since 2023.05.10 ~ )
SOP은 대부분의 웹 브라우저에서 채택하고 있는 보안 정책으로, 보안을 위해 프로토콜, 호스트, 포트가 동일한 서버로만 데이터 요청을 주고 받을 수 있는 정책을 말합니다.
SOP은 엄격한 보안 정책으로 외부 데이터를 불러오진 못하지만, CSRF나 XSS 와 같은 보안 취약점 공격으로부터 안전하다는 장점이 있습니다.
💥 웹 브라우저에서 보안정책으로 SOP을 채택하는 이유
- 브라우저는 기본적으로 사용자가 방문하는 사이트를 신뢰하지 않기 때문에, 다른 서버에서 받아온 데이터는 차단합니다.
- 브라우저는 토큰이나 쿠키 등과 같이 사용자의 정보 데이터를 받아와 저장하는데, 만약 제 3자가 이를 탈취해 정보를 변조하여 서버에 보내면 심각한 보안 문제가 발생할 수 있기 때문입니다.
💥 동일 프로토콜, 호스트, 포트란 ?
SOP은 동일 출처(동일 프로토콜, 호스트, 포트)로만 응답을 허용합니다.
외부 데이터를 사용할 수 없는 SOP의 문제를 해결하기 위한 정책으로, 추가 HTTP 헤더를 사용해 서로 다른 출처간에도 데이터 요청과 응답을 할 수 있도록 허용하는 정책을 말합니다.
다음 조건을 만족하는 경우 브라우저는 해당 CORS요청을 단순 요청으로 처리합니다.
GET, POST, HEAD 중 하나일 경우
Accecss-Control-Allow-Origin 헤더를 추가해 사용자에게 응답한다.단순 요청의 조건을 만족하지 못할시 브라우저가 자동으로 프리플라이트 요청을 생성해 요청을 보냅니다.
프리플라이트 요청은 실제 요청을 보내기 전, OPTIONS 메서드로 서버측에 사전 요청을 보내 해당 출처에 대한 접근 권한이 있는지 확인하는 것을 말합니다.

프리플라이트 요청을 보내고ccess-Control-Allow-Origin 가 담겨 돌아오면 실제 요청을 보냅니다.요청 헤더에 인증 정보를 담아 보내는 요청을 말합니다.

같은 Origin에서 HTTP 통신을 하는 경우 → 요청헤더에 쿠키가 자동으로 들어가게 되지만, Origin이 다른 서버와 HTTP 통신을 할 때 요청헤더에 쿠키와 같은 인증정보를 요청헤더에 담아 보내려면 별도 설정이 필요합니다.
요청헤더에 Axios 요청일 경우 withCredentials : true 를, Fetch 요청일 경우 credentials : ‘include’ 를 넣어주어야 합니다.
credentials 옵션
- same-origin: 같은 Origin간에 요청에만 인증 정보를 담을 수 있다. (기본값)
- include: 모든 요청에 인증 정보를 담을 수 있다.
- omit: 모든 요청에 인증 정보를 담지 않는다
Access-Control-Allow-Credentials : true 를 넣어줘야 합니다.Access-Control-Allow-Origin 헤더를 *(와일드카드)가 아닌, 명시적인 URL 로 지정해야 합니다.*(와일드카드) 는 모든 출처를 허용한다는 뜻으로, 인증정보를 담은 요청의 경우, 출처를 정확하게 설정해야 한다.app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*"); // 모든 도메인
res.header("Access-Control-Allow-Origin", "https://example.com"); // 특정 도메인
});
Access-Control-Allow-Method
Access-Control-Max-Age
Access-Control-Allow-Headers
const http = require('http');
const server = http.createServer((request, response) => {
// 모든 도메인
response.setHeader("Access-Control-Allow-Origin", "*");
// 특정 도메인
response.setHeader("Access-Control-Allow-Origin", "https://codestates.com");
// 인증 정보를 포함한 요청을 받을 경우
response.setHeader("Access-Control-Allow-Credentials", "true");
const cors = require("cors");
const app = express();
//모든 도메인
app.use(cors());
//특정 도메인
const options = {
origin: "https://codestates.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" });
});
1. 프록시 설정
💥 프록시(Proxy)란?
보안 등 다양한 이유로 직접 통신하지 못하는 두 개의 컴퓨터 사이에서 서로 통신할 수 있도록 돕는 역할을 말한다.
2. 실제 프록시 사용 코드
프록시 설정
/*<-- setProxy.js -->*/
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
"/api",
createProxyMiddleware({
target:
"http://ec2-3-39-11-242.ap-northeast-2.compute.amazonaws.com:8080",
changeOrigin: true,
pathRewrite: {
"^/api": "",
},
})
);
};
프록시 사용
/*<-- api 요청 파일 -->*/
...
await axios
.post(
`/api/sendy/auth/login`,
...
📎 참고문서