cors에러란?
프로젝트 진행하면서 api요청을 하니 cors에러가 발생하였다.
cors에러란 cros-origin Resource Sharing으로 해석하면 교차 출처 리소스 공유 정책이다.
즉 다른 출처의 리소스 공유에 대한 허용 정책이다.
출처란?
출처는 Protocol, Host, Post 를 합친것으로 서버의 위치를 찾아가는데 필요한 기본 요소들을 말한다.
cors가 필요한 이유
cors전에 sop(same-Origin policy)가 있다.
sop는 동일한 출처에 대한 정책으로 동일한 출처에 있는 리소스는 접근 가능하고
다른 출처의 자원은 접근 불가능 한것이다.
보안상 당연해 보이지만 그렇다고 모든 접근을 막아버리면 인터넷의 기능을 하지 못할것이다.
그래서 cors정책이 등장한것이다.
서로 다른 서버에 접근은 해야하고 보안상 문제도 해결해야 하기때문에
몇 가지 정책을 만들고 그 정책에 부합하는 요청만 다른 출처의 리소스에 접근을 허용하게 되었다.
이 정책이 cors이다.
cors의 동작 해결
클라이언트에서 요청을 할때 브라우저는 http헤더에 origin을 담아 보낸다. (ex http://localhost:3002)
서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다. (ex http://localhost:8080)
클라이언트에서 origin과 서버의 Access-Control-Allow-Origin을 비교한다.
브라우저는 이 둘을 비교해 차단할지 말지 결정한다.
즉 서버에서 헤더의 Access-Control-Allow-Origin에 허용할 출처를 적어 응답하면 해결할 수 있다.
cors의 상세 동작 3가지
1.예비요청
대분의 api 요청의 동작하는 방법으로 브라우저가 요청을 한번에 보내지 않고 OPTIONS이라는 메소드로
예비 요청을 보낸다. 이 요청 헤더에는 origin이 들어있고 이에 서버는 응답 헤더에 Access-Control-Allow-Origin
을 보내 cors정책 에따라 허용 가능한경우 본 요청을 보낸다.
(보안은 강화 되지만 요청이 많을경우 성능이 저하되기 때문에 브라우저 캐시 사용하여 사용)
2.단순요청
예비요청 생략하고 바로 서버에 본요청 보낸후 받은 Access-Control-Allow-Origin으로 cors정책 검사
특정 조건에선만 가능 (특정 메서드, 헤더, ContentType 일때만)
3.인증된 요청
클라이언트가 서버에게 자격 인증 정보를 실어 요청할때 사용되는 요청이다.
자격 인증이란 쿠기, 토큰 값 등을 말한다.
cors 해결 코드
프로젝트에서 직접 적용해 보겠다.
개인프로젝트는 그턍 프론트에서 무시하는 방법으로 했었는데
이번 프로젝트에선 백엔드에서 제대로 설정 해보았다. 스프링에서 처리를 해보았기 때문에
개인프로젝트 nest에도 적용해보겠다.
스프링부트 cors 해결
1. @CrossOrigin 사용
컨트롤러 클래스나 메서드에 @CrossOrigin(origins = " ") 이런식으로 orgin을 담아서 보내준다.
2. WebMvcConfigurer 인터페이스 사용
WebMvcConfigurer 인터페이스를 구현하는 configuration클래스를 만들어
addCorsMappings()메서 드를 오버라이딩한다. addCorsMappings() 메서드에서 cors구성을 할 수 있다.

3. global Cors 사용
application.properties / application.yml 파일에 직접 cors설정을 전역으로 해준다.
4. Filter 사용
커스텀 Servlet Filter를 직접 cors 설정을 구현하여 사용한다.
cors 정책에 대해 세밀한 제어가 필요한 경우 사용한다.
5. Spring Security 사용
spring security를 사용할 경우 cors 설정은 시큐리티 설정에 들어가야한다.
프로젝트 때도 WebMvcConfigurer 설정과 겹쳐서 에러가 났었다.
고친 코드에서도 securityconfig에다가 WebMvcConfigurer를 같이 구현하여 짬뽕으로 사용하고 있었다. 수정해야겠다.
WebSecurityConfiguerAdapter를 상속받고 시큐리티 설정해주는 configure 메서드에 cors 설정을 추가해 준다.
시큐리티 관해선 따로 정리 더 하겠다.
라고 생각 했는데 spring security5부터는 WebSecurityConfiguerAdapter가 지원 중단이라 한다
시큐리티 설정 하는 방법이 configure메서드 사용과 filterchain 두가지가 있었는데 이제 filterchain으로 해야한다고 한다.

filterchain에 CorsConfigurationSouce로 설정한것을 등록하려면 또 따로 CorsFilter로 등록해야하고 번거러워 보인다.
이렇게 보니 그냥 corsConfig로 따로 빼주는게 더 나을거 같아 보인다.

이렇게 CorsConfig에 설정은 해준 뒤

SecurityConfig에서 filterchain에 등록 해준다.
SecurityConfig에 따로 등록안해주고 아래처럼 그냥 Spring mvc에서 돌려도 작동하는 거 같다.

아마 내부 동작까지는 모르겠지만 시큐리티에서 한번에 같이 하는게 좋지 않을까 싶다...
나중에 기회가 되면 더 깊게 공부해봐야 할거 같다.
NestJs Cors 설정
그전에 했던 개인 프로젝트에서 cors를 그냥 프론트에서 다 무시하는 형식으로 했었던거 같아서
해당 프로젝트에서 Cors설정을 해주려한다.
nestjs는 자체적으로 cors 미들웨어를 제공하기때문에 설정 방법은 간단하다.

위 처럼 main.ts에서 모듈을 생성할때 같이 설정해주면된다.

이렇게 해주면 cors는 default값으로 설정된다.
따로 설정 해주려면

이렇게 enableCors를 사용해 설정해주면 된다.
추가적으로 MaxAge에 설명 하면 위에서 설명한 cors의 예비요청을 캐시 담아 놓는 시간을 의미한다.
캐시는 클라이언트 브라우저에 저장된다.
'프로젝트' 카테고리의 다른 글
| [프로젝트] 시스템 모니터링 (grafana, prometheus) (0) | 2024.04.11 |
|---|---|
| [aws] IPv6와 CIDR (0) | 2024.04.05 |
| [프로젝트] 리프레시 토큰 (0) | 2024.03.22 |
| [aws] aws 보안그룹 설정, bastion (0) | 2024.03.06 |
| aws 구조 (0) | 2024.02.19 |