Web

SOP(Same Origin Policy, 동일 출처 정책)와 CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)

studioesso 2025. 4. 17. 15:59

웹 상에서 클라이언트 - 서버 통신 시 인증 정보가 쿠키에 저장되어 HTTP 통신에 사용됩니다.

 

이 때 악의적으로 클라이언트 권한을 탈취해 HTTP 요청을 보내고 응답을 받아 받을 수 있는데, 이는 보안 위협에 해당합니다.

 

이를 위해 브라우저에서는 응답 받은 데이터를 악의적인 페이지에서 읽지 못하게 하기 위해 동일 출처 정책(SOP)을 사용합니다.

 

동일 출처 정책 (SOP, Same Origin Policy) : 현재 페이지 출처가 아닌 다른 출처로부터 온 데이터를 읽지 못하게 하는 브라우저 정책


SOP 예시

 

오리진 (Origin) : 브라우저가 가져온 정보의 출처를 의미합니다.

 

오리진은 프로토콜, 호스트, 포트가 모두 동일해야 같다고 인정합니다.

 

Origin : https://naver.com/index.html

 

https:// -> 프로토콜

naver.com -> 호스트

 

포트는 일반적으로 생략됩니다만, 표기될 경우 호스트:포트 (naver.com:1234/index.html) 의 형태로 표기됩니다.

 

위의 내용에 따르면 아래와 같은 URL은 Same Origin이 아닙니다.

1. http://naver.com/index.html

2. https://hack.naver.com/index.html

3. https://naver.com:33880/index.html

 


CORS (교차 출처 리소스 공유, Cross Origin Resource Sharing)

- sop 제한에 예외적으로 cross origin 데이터를 읽을 수 있게 하는 개념

 

cors는 웹 개발을 하다보면 거의 무조건 맞닥뜨리는 개념인데요.

웹 서비스를 개발하다 보면 합의하에 sop에 예외적으로 리소스를 공유해야하는 상황이 있을 수 밖에 없습니다.

이럴 때 CORS로 위 SOP 예시처럼 출처가 달라도 사전에 정해놓고 리소스를 공유하는 방법을 사용합니다.

 

보통 was(or api) 서버와 앞 단의 web 서버 간 통신 시 해당 에러가 자주 발생하는데요,

이럴 때는 백엔드 서버쪽 미들웨어로 cors 설정으로 web 서버를 등록해주면 됩니다.

 

fastapi 예시

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://127.0.0.1:3000", "http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

@app.get("/")
def read_root():
    return {"Hello": "World"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)

 

allow_origins에 신뢰하는 수신 서버 주소를 등록해주면 됩니다.

 

예시에서는 개발 과정에서 로컬에 띄워져 있는 웹서버의 주소를 그대로 등록했습니다만,

실제 프로덕션 환경에서는 환경 변수로 관리해주면 됩니다.

 

이 외에도 CORS를 적용하기 위한 다른 여러가지 방법들이 있는데, 환경에 맞게 적용하시면 됩니다.