프로젝트가 끝나고 쉬고있는 와중에
백엔드 부분 하시던 부장급 개발자분이 이번에 리액트를 처음 하셔서 공부를 하시다가 이거 어떻게 하냐 질문을 했는데
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
이런 에러가 떠있는걸 보고
"어? 이건 리액트가 아니라 백엔드에서 고치셔야 하는데요 ? ..."
대충 설명을 드렸는데도 이해를 못 하셔서 그냥 스프링 쪽 코드를 작성해서 보내드렸다..
CORS (Cross Origin Resource Sharing) 란 ?
우선 일반적으로 Spring 을 통해서 만든 주소 ex) localhost:8080
react를 통해 만든 주소 ex) localhost:3000
(앞에 http:// 프로토콜은 생략)
이렇게 백엔드의 주소와 프론트의 주소가 다르게 생성되는데
여기서 Origin (출처)는 프로토콜 + Host + Port 을 말하며
최신 브라우저에 공통적으로 있는 동일 출처 정책 때문인데
동일하지 않은 출처에서 리소스를 가져오게 될 경우 하이재킹이나 해킹을 당할 위험이 크기 때문에 최신 브라우저에선 CORS 에러를 통해 막고 있어
출처가 다른 경우의 리소스를 받기 위해선 CORS 즉 교차 출처 리소스 공유에 대한 설정이 필요한데
프록시 서버를 쓴다던지 CORS 정책을 꺼버린다던지 할 순 있지만 보안을 위해 생긴 정책을 마음대로 꺼버리는건 위험하기 때문에
해결책
컨트롤러에 따라서 출처 허용을 주고싶다면
@CrossOrigin(origins = "http://localhost:3000") // 특정 출처 허용전역적으로 출처 허용을 주고 싶다면
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 모든 경로 허용
.allowedOrigins("http://localhost:3000") // 특정 출처 허용
.allowedMethods("GET", "POST", "PUT", "DELETE") // 허용할 HTTP 메서드
.allowedHeaders("*") // 모든 헤더 허용
.allowCredentials(true); // 인증 정보 허용 (쿠키 등)
}
};
}
}
- Spring Security 를 사용한다면 ? (securityconfig)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable()) // CSRF 비활성화
.cors(cors -> {}) // CORS 활성화
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/**").permitAll() // API 요청 허용
.anyRequest().authenticated()
)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
}
- spring boot 를 사용한다면? (properties 파일에서)
spring.web.cors.allowed-origins=http://localhost:3000
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE
spring.web.cors.allowed-headers=*
spring.web.cors.allow-credentials=true
CORS 에러 같은 경우 프론트 단에서 사실상 해결 방안이 없는게 ...
프론트 단에 접근하기 전에 접속을 차단하는거라 백엔드 측에서 최대한 해결을 해야한다
'CS' 카테고리의 다른 글
지역 변수와 멤버 변수 (1) | 2024.01.21 |
---|---|
컴퓨터가 음수와 양수를 표현하는 방법, 2의 보수 (0) | 2024.01.18 |
프로그래밍 식별자 표기법 5가지 (0) | 2024.01.18 |