개요
면접 스터디 진행중 cors 에러 발생 시나리오에 대해 간단히 정리해둔것을 가져와봤다.
CORS의 개념
Same-Origin Policy를 기반으로한 브라우저의 보안정책이다.
브라우저는 같은 출처에서만 API 요청을 허용하기에 따라서, 다른 도메인, 프로토콜 또는 포트를 가진 서버로부터 자원을 요청할 경우 CORS 에러가 발생할 수 있다.
예외로 부모-자식 관계의 부모-서브 도메인에서는 발생하지 않는다. (어떻게 보면 당연한..)
[프론트] api 요청 프록시 설정
백엔드 서버가 EC2나 다른 클라우드 환경에 있고 해당 서버로 요청을 보낼 때, localhost에서 3000번 포트를 사용하여 서비스하는 경우 출처가 다르므로 CORS 오류가 발생할 수 있다.
React 등 대부분의 프레임워크에서 패키징 관련 설정을 통해 proxy설정이 가능하니 api 서버로 url을 설정해주자.
[서버] 특정/모든 출처에 대한 요청 허용
로컬에서 개발을 할 프론트를 위해 Access-Control-Allow-Origin 헤더에 특정 출처(http://localhost:3000 등) 또는 모든 출처(*)에서 오는 요청을 허용해야 해당 출처와 CORS에러 없이 통신이 가능하다.
[서버] Credentials 관련 헤더 설정, [프론트] withCredential 옵션
토큰이나 세션id 를 이용해 프로젝트를 구현해두고 withCredentials 옵션과 CORS 헤더 설정을 해놓지 않아 Preflight Request 과정에서 CORS 오류가 발생할수 있다. 혹은 에러 핸들링을 명확하게 하지 않았을때 자격증명 없음이 CORS 에러라고 명시될수도 있다.
헤더 설정이 되어있지 않아 요청차단으로 인한 에러다.
서버의 CORS 설정에 Access-Control-Allow-Credentials: true를 추가하여 자격 증명을 포함한 요청을 허용하게 되면 내부의 자격증명을 검증해보고 검증 결과에 따라서 요청을 받아들이게 된다.
클라이언트에서는 서버가 자격 증명을 처리할 수 있도록 명시적으로 요청 withCredentials = true를 추가하여 요청에 쿠키와 인증 정보를 포함시켜 보내준다.
[인프라/서버] 포트,프로토콜 이슈
로컬에서 서버/프론트 모두 실행해놓고 테스트 할때는 포트만 명시해주면 해결되는 문제이다.
하지만 Oauth2 같은 HTTPS 를 사용해야만 하는 서비스를 이용할때 HTTP 를 이용한다거나, ALB 설정에 있어서 프록시 설정을 제대로 하지 않았거나, HTTP to HTTPS 와 같은 설정을 해주지 않아서 CORS 오류가 많이 발생한다.
[인프라] Oauth2 리다이렉션 URI 미설정
OAuth2는 클라이언트 애플리케이션이 사용자를 대신해 리소스 서버에 접근할 수 있도록 권한을 부여하는 프로토콜로, 사용자 인증과 권한 부여가 아래와 같은 흐름으로 이루어진다.
- Authorization Request 클라이언트 애플리케이션이 사용자에게 로그인 페이지를 보여주기 위해 인증 서버(Authorization Server)로 리다이렉트한다.
- User Authentication 사용자는 인증 서버에서 로그인하고, 인증 서버는 사용자를 리다이렉션 URL(redirect_uri)로 다시 보낸다. 이 URL에는 인증 코드(code)가 포함되어 있으며, 클라이언트는 이 코드를 사용하여 토큰 교환을 진행한다.
- Token Exchange 클라이언트 애플리케이션은 받은 인증 코드를 사용해 인증 서버로부터 액세스 토큰(Access Token)을 요청하고 받는다.
- API 요청: 클라이언트 애플리케이션은 이 액세스 토큰을 포함하여 리소스 서버(Resource Server)로 API 요청을 보낸다.
2번의 인증코드를 포함해 리다이렉션을 보낼때 잘못된 uri 를 설정했다면 클라이언트 애플리케이션의 출처와 다르면 브라우저는 이를 크로스-오리진 요청으로 간주해서 오류가 발생할 수 있다.
'CS' 카테고리의 다른 글
DNS, TCP, TLS 통신에 대한 WireShark를 이용한 패킷 분석 (1) | 2024.06.30 |
---|