221224 CORS, Cross-Origin Resource Sharing

Jongleee·2022년 12월 24일
0

TIL

목록 보기
138/576

CORS, Cross-Origin Resource Sharing

추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여

교차출처공유 CORS, Cross-Origin Resource Sharing

다른 출처간의 리소스를 공유를 의미

  1. 동일출처정책 (SOP, same-origin-policy)

    • 해당 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호 작용 하는 것을 제한하는 보안방식
    • 악의를 가진 사용자가 정보를 탈취 하는 것 막기 위한 목적
  2. 교차출처공유가 필요한 이유

  • 웹은 오픈스페이스 환경으로 다른 출처에 있는 리소스를 사용해야 하는 경우가 존재
  • SOP의 예외조항으로 Cors 라는 정책을 지킨 요청은 출처가 다르더라도 리소스 공유를 허용

CORS 검증 흐름

  1. GET 요청인지 POST 요청인지 파악
  2. Content-Type 과 Custom HTTP Header 를 파악
  3. OPTIONS 요청을 통해 서버가 적절한 Access-Control-* 를 가졌는지 확인
  4. Access-Control 적절성 확인
    4-1. 적절한 Access-Control : 실제 XHR 트리거
    4-2. 적절하지 못한 Access-Control : Error 발생

Access-Control 부여

  1. CorsFilter 로 직접 response에 header 부여
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods","*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, X-Requested-With, Content-Type, Accept, Authorization");

        if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        }else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {

    }
}
  1. Controller 에서 @CrossOrigin 어노테이션 추가
@RestController
@RequestMapping(value = "/api/threats", produces = "application/json")
@CrossOrigin(origins = "http://front-server.com") // 컨트롤러에서 설정
public class ThreatController {

    private final ThreatService threatService;

    public ThreatController(ThreatService threatService) {
        this.threatService = threatService;
    }

이후 실제 메서드나 컨트롤러 클래스에 @CrossOrigin 어노테이션 추가

@CrossOrigin(origins = "요청이 온 곳") 
  1. WebMvcConfigurer 를 이용
  • main 함수에 Bean으로 Configurer 추가
@SpringBootApplication
public class RestServiceCorsApplication {

    public static void main(String[] args) {
        SpringApplication.run(RestServiceCorsApplication.class, args);
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://front-server.com");
            }
        };
    }

}

0개의 댓글