[cs - spring] Spring에서 cors를 해결하는 방법

링딩·2023년 5월 2일
0

Computer Science

목록 보기
49/49



CORS란?

◽ 의미

CORS는 Cross-Origin Resource Sharing 의 줄임말로, 교차 출처 리소스 공유를 의미하며, 교차 출차는 ‘다른 출처’라고 생각하면 이해하기 쉽다.
=> 즉, 다른 출처 간의 자원을 공유하는 정책을 말한다.

이해가 잘 안가니 좀 더 살펴보자


출처라는 것은

이런 식으로 url은 구성되어 있는데
이 url의 구성요소 중 출처(Origin)는 Protocol과 Host, 그리고 :80 , :443 같은 포트 번호까지 모두 합친 것을 의미한다.

CORS는 출처가 다르기 때문에 발생한다.

  • 즉, SOP를 준수해야 한다.
    -> 그대로 같은 출처만 허용한다는 정책을 의미한다.
  • 과거에는 보안을 위해 엄격하게 같은 출처만 통신하도록 허용하였으나, 최근에는 다른 출처에 있는 리소스를 가져와서 사용하는 일이 아주 흔하므로 SOP의 예외 조항인 CORS 정책을 두게 되었다.


CORS 해결 방법

프론트엔드(ex. React)와 백엔드(ex. Spring)로 나누어 개발할 경우 CORS 이슈는 아주 흔하게 발생한다. Spring을 사용하여 CORS 이슈를 해결하는 방법은 크게 3가지가 있다.


🚨 CORS가 발생하였다.


1. CrossOrigin 사용

  • CORS 정책을 설정해 줄 대상에 @CrossOrigin 어노테이션을 활용
@CrossOrigin(originPatterns = "http://localhost:8080")
@RestController
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "로그인 성공! ID: jayon, PW: 1234";
    }
}

위 쪽에 해당 어노테이션을 붙이고, originPatters 속성을 통해 요청을 허용할 출처를 적어준다.

  • 그러나... 설정해야할 대상이 많아지면 코드가 점점 늘어나기에 간단하지만 비추..


2. WebMvcConfigurer 설정

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods(HttpMethod.GET.name());
    }
}
  • WebMvcConfigurer를 상속한 클래스를 만들고, addCorsMappings() 를 재정의하면 된다.
    • addMapping() 메소드를 통해 CORS 정책을 적용할 'URL 패턴'을 설정하고, allowedOrigins() 메소드를 통해 허용할 출처를 적어준다.
      -> 이 외에 allowedMethods() 메소드를 통해 GET, POST와 같은 HTTP 메소드의 종류도 제한할 수 있다. (구체적으로 가능)



3. 프록시 서버를 사용하자

  • 400, 500번대와 같은 상태 코드를 반환하지 않고 200번 코드를 반환한다.
@Controller
public class UserController {

    @GetMapping("/api/view")
    public String view() {
        return "/cors";
    }

    @GetMapping("/api/proxy")
    @ResponseBody
    public String proxyView() {
        String url = "http://localhost:1000/login";

        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject(url, String.class);
    }
}
  • CORS 이슈는 브라우저 단에서 서버의 Access-Control-Allow-Origin 값을 보고 방금 보낸 요청의 출처가 허용되는지 판단하고, 허용되지 않으면 발생한다고 이야기하였다.
    => 즉, 요청을 보내는 쪽에서 프록시 서버를 만들어 간접적으로 전달하면 응답을 받을 수 있다.

그리고 이것을 'localhost:8080/api/proxy' 로 요청을 보내면 정상적으로 CORS 오류가 해결된 것을 확인할 수 있다.

Q. 왜 된 것일까?

A.
RestTemplate를 통해 서버와 서버 간 통신을 하였으므로
-> 이를통해 CORS 이슈 없이 응답 데이터를 얻어올 수 있고, 브라우저 입장에서는 요청을 보낸 출처와 응답을 받은 출처가 같으므로 응답 데이터를 정상적으로 렌더링 할 수 있었다.




profile
초짜 백엔드 개린이

0개의 댓글