본문 바로가기
etc

CORS

by 스르나 2021. 3. 14.

CORS (cross origin resource sharing)란?

cors는 웹환경에서 서로 다룬 출처에서 온 자원을 어떻게 처리할지에 대한 것이다. cors가 나온 이유는 sop(same origin policy)정책 때문이다. 웹 환경을 오픈된 환경이기 때문에 외부의 공격에 쉽게 노출이 된다. 그렇기 때문에 같은 출처에서 온 자원만을 허용하는 것이다. 참고로 cors가 올바른지는 서버, 클라이언트가 하는 것이 아니라 브라우져에서 확인을 한다.

 

여기서 출처란 프로토콜 + 호스트 + 포트 이다.

 

위처럼 프로토콜,호스트,.포트번호가 같다면 같은 출처인 것이다. 뒤에 쿼리부붙은 달라도 상관없다.

 

 

 

우리가 어떤 요청을 하면 요청 메시지는 위처럼 생기는데(리액트에서 axios를 이용해 post 요청을 한 것이다.) 밑에서 3번째 울에 Origin:http//localhost:3000이라고 돼있는것을 볼 수 있다. 이 Origin에 출처에 해당한다.

 

 const post= async ()=>{
    try{
      const response= await axios.post('http://localhost:8080/user',{
        id:id,
        password:password,
        name:name
      })
      alert(`${response.data.id} ${response.data.name} ${response.data.password}`);
    }catch(e){
      console.log(e);
    } 
  }

저 post 요철의 소스 코드이다. 여기서 보면 주소를 localhost:8080으로 한것을 볼 수 있다.

 

@PostMapping("/user")
    public User postUser(@RequestBody User user){
        userRepository.save(user);
        return user;
    }

그리고 서버 사이드에서는 그냥 요청을 받고 response body에 넣어서 보내준다. 분명 서버에서 보내온것은 http://locahost:8080이다.

 

그럼 요청과 응답은 아래와 같다.

보면 포트가 다르기 때문에 출처가 다른 것이 된다.

 

결과를 보면 post 요청에 대해 cors 에러가 난것을 볼 수 있다.

 

 

해결 방법

해결 방법에는 클라이언트에서 해결하는 방법과 서버에서 해결하는 방법이 존재한다.

1. 클라이언트

클라이언트에서 해결하는 방법은 웹팩 개발 서버에서 제공하는 프록시를 이용하는 방법이다.

 

출처: https://react.vlpt.us/redux-middleware/09-cors-and-proxy.html

 

웹팩 개발서버의 프록시를 이용하면 우리가 요청한 주소에 바로 요청을 하는 것이 아니라, 클라이언트의 요청을 개발서버에서 받는다. 그리고 개발 서버에서 백엔드 서버로 요청을 하고, 백엔드 서버의 응답을 클라이언트가 받는 것이 아니라 개발서버에서 받고 개발서버에서 클라이언트로 보내는 것이다.

 

사용방법은 리액트에서 만든 앱이라면 package.json에서 아래와 같이 proxy를 명시해주면 된다.

 

 

그다음 다시 요청을 하는 부분에서 출처를 지우고 쿼리만 넣어 주면 된다.

 

const post= async ()=>{
    try{
      const response= await axios.post('/user',{ // 출처를 지웠다!
        id:id,
        password:password,
        name:name
      })
      alert(`${response.data.id} ${response.data.name} ${response.data.password}`);
    }catch(e){
      console.log(e);
    } 
  }

 

 

2. 백엔드 서버

다음으로는 백엔드 서버에서 처리 하는 방법이다.

 

백엔드 서버에서는 응답 헤더에 올바른 Origina(ccess-control-allow-origin)이 나올 수 있게 처리를 해줘야 한다.

 

스프링에서는 다음과 같이 2가지 방법이 존재한다.

 

1. WebMvcConfigure를 이용한 방법

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 모든 요철
                .allowedOrigins("http://localhost:3000"); // 허용할 origin
    }
}

 

2. @CrossOrigin을 이용한 방법

@CrossOrigin(origins = "http://localhost:3000")
    @PostMapping("/user")
    public User postUser(@RequestBody User user){
        userRepository.save(user);
        return user;
}

 

먼저 WebMvcConfigure를 이용한 방법은 따로 설정을 만들어 이용하는 방법이고, @CrossOrigin을 이용하는 방법은 특정 요청마다 어노테이션을 이용해서 처리하는 방법이다.

 

2가지 방식을 이용하면 응답에 위처럼 Access-Controll-Allow-Origin이 나온다.

 

 

추가적으로 요청 과정을 보면 OPTIONS 요청을 한번 하는 것을 확인 할 수 있는데 이 OPTIONS 요청이 cors를 확인 하는 것이다. 즉, 예비 요청을 보내서 cors 에러가 안나는지 확인을 하는 것이다.

이러한 방법을 preflight request라고 한다. 그리고 캐시가 되기 때문에 동일한 요청에 대해서는 다시 하지 않는다.

 

자세한 내용은 아래 주소를 참고하자.

 

developer.mozilla.org/en-US/docs/Glossary/Preflight_request

 

Preflight request - MDN Web Docs Glossary: Definitions of Web-related terms | MDN

Preflight request A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-

developer.mozilla.org

 

다른 2가지 방식도 있는데 사용 방법이 까다롭고, 사용 가능 범위가 좁아서 따로 설명하지 않고 참고 주소만 남겨 놓는다.

 

developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests

 

Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Cross-Origin Resource Sharing (CORS) Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. C

developer.mozilla.org

 

developer.mozilla.org/en-US/docs/Web/HTTP/CORS#requests_with_credentials

 

Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Cross-Origin Resource Sharing (CORS) Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. C

developer.mozilla.org