CORS(Cross-Origin Resource Sharing)는 교차 출처 리소스 공유 정책이라고 해석할 수 있다.
즉 다른 출처의 자원에 관한 공유 정책이라고 보면 될 것이다.
[CORS 에러 예시]
🚨Access to fetch at ‘https://myhompage.com’ from origin ‘http://localhost:3000’ has been blocked by 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.
💬 'https://myhomepage.com'에서 'https://localhost:3000' 출처로 가져올 수 있는 액세스가 CORS 정책에 의해 차단되었습니다. 요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다. 불투명한 응답이 필요에 적합한 경우, 요청 모드를 'no-cors'로 설정하여 CORS가 비활성화된 리소스를 가져오십시오.
해석한 내용처럼 CORS 정책으로 인해 localhost:3000 주소의 자원을 가져오는 데에 있어서 차단이 된 것이다.
Easily add (Access-Control-Allow-Origin: *) rule to the response header.
그러면 브라우저 오른쪽 상단에서 확장 프로그램을 활성화 시킬 수 있다. 해당 프로그램을 활성화 시키게 되면,로컬(localhost) 환경에서 API를 테스트 시, CORS 문제를 해결할 수 있다.
2.프록시 사이트 이용하기
프록시(Proxy)란 클라이언트와 서버 사이의 중계 대리점이라고 보면 된다.
즉, 프론트에서 직접 서버에 리소스를 요청을 했더니 서버에서 따로 설정을 안해줘서 CORS 에러가 뜬다면,모든 출처를 허용한 서버 대리점을 통해 요청을 하면 되는 것이다.
다만 현재 무료 프록시 서버 대여 서비스들은 모두 악용 사례 때문에api 요청 횟수 제한을 두어 실전에서는 사용하기 무리이다. 따라서 테스트용이나 맛보기용으로 사용하되, 실전에서는 직접 프록시 서버를 구축하여 사용하여야 한다.
3.서버에서 Access-Control-Allow-Origin 헤더 세팅하기
직접 서버에서 HTTP 헤더 설정을 통해 출처를 허용하게 설정하는 가장 정석적인 해결책이다.
CORS에 연관된 HTTP 헤더 값으로는 다음 종류가 있다. (이들을 모두 설정할 필요는 없다)
# 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함.
# * 이면 모든 곳에 공개되어 있음을 의미한다.
Access-Control-Allow-Origin : https://naver.com
# 리소스 접근을 허용하는 HTTP 메서드를 지정해 주는 헤더
Access-Control-Request-Methods : GET, POST, PUT, DELETE
# 요청을 허용하는 해더.
Access-Control-Allow-Headers : Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization
# 클라이언트에서 preflight 의 요청 결과를 저장할 기간을 지정
# 60초 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않는다.
Access-Control-Max-Age : 60
# 클라이언트 요청이 쿠키를 통해서 자격 증명을 해야 하는 경우에 true.
# 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다.
Access-Control-Allow-Credentials : true
# 기본적으로 브라우저에게 노출이 되지 않지만, 브라우저 측에서 접근할 수 있게 허용해주는 헤더를 지정
Access-Control-Expose-Headers : Content-Length
서버에서 직접 Access-Control-Allow-Origin 헤더를 세팅하는 것은 사용하는 서버에 따라 다르다.
나는 Spring을 주로 다루었기 때문에 Spring에 대한 세팅을 다루자면,
// 스프링 서버 전역적으로 CORS 설정
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080", "http://localhost:8081") // 허용할 출처
.allowedMethods("GET", "POST") // 허용할 HTTP method
.allowCredentials(true) // 쿠키 인증 요청 허용
.maxAge(3000) // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
}
}
CorsConfig 라는 Access-Control-Allow-Origin 헤더를 세팅하는 설정 클래스를 만들어준다.
localhost:8080 , localhost:8081 출처에 대해서 GET, POST 방식의 요청을 허용하겠다는 뜻이다.
// 특정 컨트롤러에만 CORS 적용하고 싶을때.
@Controller
@CrossOrigin(origins = "*", methods = RequestMethod.GET)
public class customController {
// 특정 메소드에만 CORS 적용 가능
@GetMapping("/url")
@CrossOrigin(origins = "*", methods = RequestMethod.GET)
@ResponseBody
public List<Object> findAll(){
return service.getAll();
}
}
해당 컨트롤러에서만 CORS를 적용할 수도 있다.
@CrossOrigin으로 CORS를 적용한다.(아무 출처나 허용, method는 GET 방식)
최근에 진행했던 프로젝트에서는 조금 다른 방식으로 CORS를 허용하였다.
@Slf4j
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter(){
UrlBasedCorsConfigurationSource source =new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);// 내서버가 응답을 할 떄 json을 자바스크립트에서 처리할 수 있게 할지를 설정하는 것
config.addAllowedOrigin("https://haetae.shop/");
config.addAllowedOrigin("https://haetae.shop/5000");
config.addAllowedOrigin("https://localhost:5000");
config.addAllowedOrigin("https://localhost:8443");
config.addAllowedOrigin("https://cheiks.shop/");
config.addAllowedOrigin("http://localhost:3000");
config.addAllowedOrigin("https://www.liergame.link/");
config.addAllowedOriginPattern("*");//모든 ip의 응답을 허용하겠다. // 게시글 테스트 떄문에 잠시 열어둠
config.addAllowedHeader("*");//모든 header의 응답을 허용하겠다.
config.addAllowedMethod("*");//모든 post,get,putmdelete,patch 요청울 허용하겠다.
config.addExposedHeader("*");
source.registerCorsConfiguration("/lier/**",config);
log.info("회원관리 기능 절차(jwt) -> CorsConfig - corsFilter 메소드");
return new CorsFilter(source);
}
}
CorsConfig 와 관련된 설정 클래스를 마찬가지로 만들어준다.
CorsConfiguration 객체를 사용하여 설정값을 정해주었다.
- setAllowCredentials(true) : 내 서버가 응답을 하게 되어 json을 넘기게 되면 javascrpit에서 처리할 수 있도록 하는 Cors설정이다.
- addAllowedOrigin(~) : 허용하고자 하는 출처의 ip를 기입한다. 즉, 모든 ip,url에 대해 응답을 허용하게 된다.
- addAllowedHeader(~) : 어떠한 헤더에 대한 응답을 허용하겠다는 뜻이다.