이번 강의에서는
Spring Security 프레임워크에 도움을 받아
Spring Boot 웹 애플리케이션 안에서
CORS 관련 해결방안들을 구현해봅시다
저번에 설명한 것처럼
CORS 설정은 웹 애플리케이션 내에서
controller level 또는 대외적으로
설정할 수 있습니다
대외적 방법이 더 나은 선택이기 때문에
그 방법을 따르도록 하겠습니다
ProjectSecurityConfig 클래스 안
메소드에 http 변수 다음에 생성했던
SecurityFilterChain의 bean으로
CORS 라는 새로운 메소드를 불러올 수 있습니다
이 CORS 메소드를 불러오면
또 다른 메소드를 호출해야 하는데
바로configureSource 입니다
이 configureSource 메소드에서
CorsConfigurationSource의 객체를 전달해야합니다
여기 보시면 코드 몇 줄을 붙혀 넣었습니다
이게 무엇인지 봅시다
CorsConfigurationSource는 인터페이스이기 때문에
익명의 내부 클래스를 하나 만들었습니다
여기 보이는 게 전부 내부 익명 클래스이며
그 안에다가
추상 메소드를 덮어써서
이 인터페이스의 객체를
인터페이스 내에 생성해보겠습니다
메소드 이름은 getCorsConfiguration입니다
이 메소드에는
먼저 CorsConfiguration의 객체를 생성해야 합니다
이 CorsConfiguration 객체로
이전 강의에서 설명한
여러가지 CorsConfigurations들을 전달해야 합니다
가장 중요한 설정은 setAllowedOrigins 입니다
이 메소드만을 사용해서
어떤 출처, 도메인, 서버들이
백엔드와 소통하도록 허용되었는지 설정합니다
Angular UI 애플리케이션이
localhost:4200에 구축되었으니
만약에 여러 애플리케이션들이 있다면
쉼표로 구분한 값들로 정의할 수 있습니다
이런 정보들을 기입하고
컴파일 에러가 발생하는데
이는 CORS와 CSRF가 서로 다른 설정이기 때문입니다
서로 다른 설정을 정의할 때는
앞서 설명했듯이 메소드를 불러와야 하고
그 다음에는
이렇게 컴파일 에러가 해결됩니다
여기에 내용을 저장하고 구축해보도록 하겠습니다
구축이 끝나면
웹 애프리케이션을 다시 시작하여
이 설정들이 올바르게
반영됐는지 확인합니다
마찬가지로 처음
현재 실행 중인 인스턴스들을 중지하겠습니다
그리고 EasyBankBackendApplication열어줍니다
여기서는 디버깅 모드로 애플리케이션을 시작할 것입니다
포트 8080에서 애플리케이션을 실행해줍니다
이제 Spring Boot 백엔드 애플리케이션이
우리가 만든 Angular UI 애플리케이션과 소통해도
괜찮은 상황입니다
이제 UI 애플리케이션 안에 있는
공지사항 페이지를 테스트해봅시다
우선 콘솔부터 다 지워주시고
지금 페이지인 /notices 페이지를 새로고침 해줍니다
그리고 이번엔 에러가 없는 것을 확인할 수 있습니다
그리고 이 페이지에 표시되는
모든 공지사항(notices) 정보들을 받고 있습니다
네트워크 탭에 가보면 브라우저가 만든
pre-flight 요청을 확인해볼 수 있습니다
이것이 브라우저가 만든 pre-flight 요청입니다
type이 pre-flight인 게 보이십니까?
다른 요청들은 보시다시피
백엔드 서버가 받은
진짜 요청들로 되어있습니다
그래서 응답 안에서
모든 공지사항 정보를 볼 수 있습니다
pre-flight 요청에 가보면
헤더에서 발생했고
그러니까 이게 전부 백엔드에서 받은
응답 헤더들입니다
이게 컨트롤이 허용된 출저들의
접근입니다
이것이 백엔드 서버에서 보내는
헤더인데 출처 정보는
localhost:4200
Max age 3,600초
그리고 allowed method는 애스터리스크(*)를 사용했고
notice가 GET이므로
allowed credentials 는 true입니다
이 응답 헤더를 기반으로
브라우저는
두 개의 다른 출처 사이의
CORS 소통을 활성화할지 말지 결정합니다
여기에 모든 걸 활성화 했기 때문에
잘 작동되고 있습니다
아무리 많이 새로고침을 해도
잘 작동됩니다
또 하나 재밌는 건
제가 여기 쉬는 구간을 유지했다는 것입니다
제가 페이지를 새로고침해도
REST API가 불러와지지 않습니다
그 이유는 controller에서
공지사항(notices) 정보와 함께
cacheControl 정보를
cacheControl.maxAge 60초로 보내고 있기 때문입니다
그 말은 브라우저가 다음 60초 동안
notices API를 불러오지 말라는 것입니다
처음 받은 공지사항(notices) 정보들을
재사용할 수 있고
그리고 동일한 정보가 UI에 표시됩니다
이는 웹 애플리케이션에서
몇몇 큰 작업들을 수행할 때 사용됩니다
어떠한 데이터들이
자주 바뀔 것 같지 않다고 생각되면
그럼 요구사항에 따라
이 캐시를 사용하면 됩니다
2분 또는 5분 동안 요구사항에 따라
캐시가 진행될 수 있습니다
이것은 웹 어플리케이션에서
백엔드 요청을 만들지 않으면서
몇몇 작업들을 개선시키고
브라우저는 캐시 내의 데이터를 활용할 것입니다
그래서 REST API 가 발생하지 않는 것입니다
한 번만 더 해보겠습니다
왜냐하면 60초가 지났습니다
이번에는 쉬는 구간에 멈춥니다
REST API 요청이 발생했다는 것입니다
풀어보도록 하겠습니다
그리고 계속 새로고침해보면
캐시의 데이터를 사용하는 걸 볼 수 있습니다
이제 여러분들이 웹 애플케이션에서
CORS 관련 문제들을 다루는 걸
잘 이해하셨길 바랍니다
절대 CORS를
보안 공격이나 위험처럼 취급하지 마시기 바랍니다
브라우저가 제공하는
보호막입니다 출처가 다른 두 소통을
막아주는 역할을 하는 것입니다
정당한 상황에서
출처가 다른 곳에서의 소통을 성사 시키고 싶다면
그건 브라우저에게
pre-flight 요청을 만들도록 하는 것이
백엔드의 역할입니다
실제로 저는 많은 개발자들이 다투는 것을 봅니다
예를 들어 팀 A가 개발한 UI 애플리케이션이 있고
Spring Boot 애플리케이션와 같은 백엔드 애플리케이션을
개발한 팀 B가
있다고 가정해보면
백엔드 팀은 항상 "우리 쪽은 잘 작동돼
여기 Postman 테스팅을 했다는
스크린샷 증거 사진이야" 라면서
UI 개발자들에게 책임을 전가합니다
그러면 UI 개발자들은 이렇게 말합니다
"우리 쪽에서도 잘 돼 아무 문제 없어
테스트도 했는데
백엔드와 소통이 되지 않아
그러니 문제는 백엔드 쪽에 있어"
그러니 항상 이런 식으로
책임 전가 싸움이 발생합니다
하지만 이제 여러분은
프로젝트에서 이러한 상황이 발생했을 때
문제의 원인을 알고 있습니다
그들을 도와주고 잘 알려주시기 바랍니다
그리고 CORS 정보들을 설정하는 건
항상 백엔드 쪽의 역할입니다
그리고 이것이 우리가 Spring Security 프레임워크를 사용해
해결하는 방식입니다
CORS 개념을 확실히 배웠을 거라고 믿습니다
다음 강의부터는 CSRF 보안 공격에 대해
자세히 다뤄보겠습니다
감사합니다 다음 강의 때 뵙겠습니다
수고하셨습니다