React를 접하면 흔히 나오는 장면인 CORS 오류.. 누구나 보게 되는 장면이라 생각된다.
클라이언트인 React는 기본적으로 locathost:3000이고 보통 서버단은 localhost:8080으로 사용하게 될 것이다.
이렇게 Origin이 다르다 보니 해당 오류가 발생하는 것이다. 해당 문제에 대해 좀 더 알아보자.
1. SOP 란?
우선 CORS를 알기전 SOP 개념에 대해 알아야 한다.
SOP(Same Origin Policy) 이란 '동일 출처 정책' 이라고 하며, 다른 Origin에서 리소스를 가지고 오거나 보내는 등 상호작용 하는 것을 제한하는 보안 방식이다.
즉, 웹 브라우저에서 보안을 강화하기 위해 동일한 Origin에서만 리소스를 주고받도록 하는 정책이다.
여기서 Origin(출처) 에 대해서도 자세히 알아보자
Origin은 위 그림에 나와있듯이 특정 도메인 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것이다. 여기서 프로토콜, 호스트, 포트 번호가 다르면 SOP을 위반하여 CORS 문제가 발생하는 것이다.
2. CORS 란?
CORS(Cross-Origin Resource Sharing) 란 '교차 출처 리소스 공유' 라고 하며, 앞서 말한 SOP에 의해 다른 Origin에서 리소스를 받아오는 것이 제한되기에 이러한 문제를 해결하기 위해 나온 정책이 바로 CORS이다.
즉, 도메인이 다른 서버끼리 리소스를 주고받을 때 보안을 위해 Origin을 설정하는 정책이라 생각하면 된다.
이제 여러 방법들을 통해 CORS 문제를 해결해 보자
3. CORS 해결
- Spring Security 사용
Spring + React를 사용한다는 가정하에 진행하면 된다.
먼저 build.gradle에 아래의 의존성을 추가해 준다.
// spring-security dependency
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
그리고 SecurityConfig 파일과 CorsConfig 파일을 작성해 준다.
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private final CorsConfig corsConfig;
@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()
.configurationSource(corsConfig.corsConfigurationSource())
.and()
.formLogin().disable()
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests()
.requestMatchers("/**").permitAll()
.anyRequest().authenticated();
return httpSecurity.build();
}
}
@Configuration
public class CorsConfig {
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(List.of("http://localhost:3000"));
configuration.setAllowedMethods(List.of("*"));
configuration.setAllowedHeaders(List.of("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
CorsConfig에서 React의 Origin인 localhost:3000을 넣어주고 작성해 준다. 그리고 SecurityConfig에서 작성한 CorsConfig를 추가해 주면 CORS 오류를 해결할 수 있다.
- Proxy 사용
React 상에서 진행을 해주면 된다.
우선 http-proxy-middleware를 설치한다.
npm install http-proxy-middleware --save
설치 후 React 최상위 폴더에서 아래와 같은 내용으로 작성하여 setupProxy 파일을 만들어준다.
target 부분에 서버 도메인을 작성해주고 changeOrigin을 true 값을 주면 된다.
// setupProxy.ts
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = (app) => {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:8080",
changeOrigin: true
})
);
};
그 후 사용하고자 하는 곳에 setupProxy에서 설정한 "/api" 를 넣어준다. 나는 axios를 사용하기에 아래와 같이 작성하였다.
...
useEffect(() => {
const getListData:object = {
pageNo: pageNo,
institutionNo: institutionNo,
searchCategory: searchCategory,
searchText: searchText,
}
const boardList = async () => {
await axios({
method: "POST",
url: '/api/board/boardList', // 맨앞에 설정한 proxy의 '/api' 넣어주기
data: JSON.stringify(getListData),
headers: {'Content-type': 'application/json'}
}).then((res):void => {
setBoardList(res.data.data.boardList);
setTotalPage(res.data.data.totalPage);
}).catch((err):void => {
console.log(err.message);
});
}
setTimeout(() => {boardList().then();}, 0);
}, [pageNo, institutionNo, searchCategory, isSearchActive])
...
만약 axios를 사용하면서 baseURL을 설정하였다면 설정한 baseURL을 제거해 주어야지 정상적으로 동작할 것이다.
위 방법은 자신이 사용하는 서버뿐만이 아닌 다른 곳의 API를 사용할 때도 사용해 주면 좋다. 보다 유연하고 다양하게 대처할 수 있기에 위 방법을 추천하고 선호한다.
'JavaScript > React' 카테고리의 다른 글
[React] 리뷰 별점 기능 구현하기 (0) | 2024.07.17 |
---|---|
[React] 웹 에디터 React-Quill 사용하기 (2) (0) | 2024.06.22 |
[React] 웹 에디터 React-Quill 사용하기 (1) (0) | 2024.06.16 |
[React] Swiper 사용하기 (0) | 2024.05.22 |
[React] Jotai로 상태 전역으로 관리하기 (2) | 2024.04.28 |