본문 바로가기

기술면접준비

CORS 가 무엇인지, 문제 해결은 어떻게?

 

CORS : Cross Origin Resource Sharing

다른 출처 리소스 공유

 

출처란? 예를들어,

 https://www.podo.com/users?sort=asc&page=1#foo

 

이때, 출처는  https://www.podo.com 여기 까지 이다. 뒤에 :80 , :443 같은 포트번호까지 포함(있으면)

프로토콜(Scheme) + 호스트 

 

 

SOP : Same Origin Policy

같은 출처에서만 리소스 공유할수 있다는 정책

이것의 예외 조항이 CORS -> 이걸로 다른 출처의 리소스 요청 허가됨

 

출처의 동일여부 구분 기준?

-> 두 URL의 Scheme, host, port 이 세개만 동일하면 OK 

그런데 이걸 비교하는 로직은 애초에 브라우저에 심어져있는 스펙이다 

즉, 브라우저 단에서 적용되는 것이기 때문에 Postman같이 브라우저를 거치지 않고

서버끼리만 통신을 할땐 CORS문제같은게 발생하지 않는것!!

 

 

CORS는 어떻게 동작하는지?

  1. 웹 클라이언트 App이 다른 출처의 리소스를 요청할때는 HTTP 프로토콜로 보내고, 요청 헤더의 Origin 필드에 요청을 보내는 출처를 담아 보낸다
  2. 서버가 응답할때 응답헤더의 Access-Control-Allow-Origin이란 값에 이 리소스에 접근하는것이 허용된 출처 라고 내려주고 이후 브라우저는 자신이 보냈던 요청의 Origin과 서버응답의 Access-Control-Allow-Origin 이필드를 비교해보고 응답의 유효여부를 판단한다
  3. 세 가지 시나리오가 있다 - Preflight Request, Simple Request, Credentialed Request
    1. Preflight Request : 예비요청, 본요청 나눠서 보냄. 예비요청으로 테스트하고 본요청 보내는거

 

 

요청에 단순히 Origin에대한 정보 뿐 아니라, 예비요청 이후에 보낼 본 요청에 대한 다른 정보들도 함께 포함 된다.

 

응답이 이런식으로 온다

 

티스토리 서버가 이 리소스에 접근 가능한 출처는 오직 evan-moon 어쩌고 뿐이라고

브라우저한테 말해줬다. 

실제 요청보낸 출처랑 다른 url이다. 결국 브라우저는 이요청이 CORS정책 위반했다고 판단하고

에러를 발생시킨다.

 

예비요청에 대한 응답일뿐이므로 200 OK가 떨어지긴 하지만, 요청 성공여부랑은 상관없는거다

브라우저가 CORS 위반여부 판단하는 시점은, 예비요청에 대한 응답을 받은 이후이기 때문!

 

 

 

해결 방법은?!

 

Access-Control-Allow-Origin 세팅하기 -> 정석대로 서버에서 저 헤더에 알맞은 값 세팅해주면 된다

와일드 카드인 *을 사용해서 모든출처의 요청을 받게되면 보안적으로 심각한 문제가 발생할 수 있으므로

출처를 명시해주는게 좋다

 

Nginx나 Apache와같은 서버 엔진의 설정에서 추가할 수도 있지만, 구체적설정이 불편하기 때문에

소스코드 내에서 응답 미들웨어를 사용해 세팅하는것이 좋다고 한다.

 

 

자바 스프링에서 응답 미들웨어 설정하는 방법?

1. Filter 

2. Interceptor

3. HandlerAdvice -> 응답처리를 중앙에서 관리하기

 

스프링에서 http요청이 거치는 순서는

FIlter -> Interceptor -> AOP이다

filter : 인코딩, 보안, 로깅 등등처리

interceptor : 인증, 권한체크, 비즈니스로직 전후 발생!

aop : 특정 메서드 실행시점에서 공통된기능(로깅,트랜잭션 등)을 처리. 메서드 전/후 처리를 한

이제 그다음 컨트롤러에 도달..?

 

Spring Security를 사용한다면, SecurityConfig에서 설정할 수 있다!

 

@Bean 

public SecurityFilterChain 어쩌고 여기서 설정한다.