Cross-Origin Resource Sharing = 교차 출처 리소스 공유
웹 어플리케이션이 다른 출처의 자원에 접근할 때, 접근 권한을 줄 수 있도록 브라우저에 알려주는 체제인 CORS를 이용해야 한다.
여기서 출처는 Http://localhost:8080
과 같이 프로토콜 + 호스트 + 포트를 말한다. 여기서 하나라도 다르면 출처가 다르다고 말할 수 있다.
예를 들어 React의 3000포트에서 Spring Boot의 8080포트로 API를 호출 할 때, 출처가 다르므로 CORS 에러가 발생한다.
CORS는 일종의 규칙, 서로 다른 출처의 어플리케이션이 마음대로 접근하는 것을 막기 위해 필요. 브라우저가 제한함
클라이언트가 서버로 API 호출 (HTTP 프로토콜 사용) | |
---|---|
↓ | 브라우저는 요청 헤더에 Origin 이라는 필드에 출처를 담아 보낸다. |
서버가 요청을 받고, 응답을 해준다. | |
↓ | 서버는 응답 헤더에 Access-Control-Allow-Origin 이라는 값에 이 리소스에 접근하는 것에 대한 허용된 출처를 내려준다. |
↓ | 브라우저는 요청 시 Origin 과 응답 시 Access-Control-Allow-Origin 두 값을 비교하여 유효한지 확인한다. |
클라이언트가 최종적으로 응답 값을 받는다. |
Access to XMLHttpRequest at 'http://localhost:8080/rest/v1/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
해당 문제는 서버로부터 Access-Control-Allow-Origin
값을 못 받았기 때문에 생기는 문제이다.
@Configuration
@EnableScheduling
@EnableTransactionManagement
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("OPTIONS", "GET", "POST", "PUT", "DELETE");
}
}
package.json
"proxy": "http://localhost:8080"
추가
axios를 통해
import axios from 'axios';
export default axios.create({
baseURL: "http://localhost:8080/rest/v1",
headers: {
"Content-type":"application/json",
'Access-Control-Allow-Origin': 'http://localhost:8080', // 서버 domain
'X-AUTH-TOKEN': `${localStorage.getItem('X-AUTH-TOKEN')}`
},
withCredentials: true
});
둘 중 하나의 방법을 선택해서 사용하면 된다.