CORS 오류 해결하기

hanana·2024년 4월 26일
0

흔히 개발하는 SPA 환경에서 쉽게 발견할 수 있는 cors문제 해결법에 대해서
정리해보려고 합니다.

아주 간단한 예시로
프론트엔드의 버튼을 누르면 서버에서 '안녕!!!' 이라는 로그를

frontend는 React,
backend는 Kotlin과 Springboot를 사용였습니다.


frontEnd

import axios from 'axios';

function LoginPage() {

    function loginBtnClick() {
        axios.get('http://localhost:8080/hello')
            .then((response) => {
                console.log(response.data);
            })
            .catch(() => {
                console.error('에러발생');}
        )
    }

    return (
        <button onClick={()=> loginBtnClick()}>누르고 싶게 생긴 버튼</button>
    )
}


export default LoginPage;

<button onClick={()=> loginBtnClick()}>누르고 싶게 생긴 버튼</button>

backEnd

@RestController
class HelloController {
    @GetMapping("/hello")
    fun hello() : String {
        println("안녕!!!")
        return "안녕!"
    }
}

axios를 통해서 서버에 요청을 보냈으나,
요청이 컨트롤러까지 오지 않고 CORS오류라는 메세지가 발생하고 있습니다.


CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)

CORS에서 말하는 출처, 즉 Origin은 URL에서 Domain 뿐만 아니라 프로토콜, 포트를 포함하는 개념입니다.

즉, 같은 localhost라고 할지라도 프론트엔드 서버는 3000번 포트, 백엔드 서버는 8080포트에 구동되고 있으므로
시스템은 출처가 다른 요청으로 인식하고 이에대한 응답을 거부하는 보안정책입니다.

'CORS는 개발자를 불편하게 하는것이 아니라, 보안위협에서 서비스를 지켜주는 정책'이라는 표현이 맞다는 생각이 듭니다.

기타 CORS에 대한 내용은 토스페이먼츠 커뮤니티에 아주 이해하기 쉽게 나와있습니다.

https://docs.tosspayments.com/resources/glossary/cors#%ED%94%84%EB%A1%9D%EC%8B%9C-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0


해결 - WebCong - allowedOrigins설정하기

프록시서버를 둔다던가, 미들웨어를 두는 방법이 있지만
저는 가장 손쉬운 방법을 사용했습니다.

백엔드에서 WebMvcConfigurer를 상속받는 WebConfig 클래스를 생성한 뒤
@Configuration 어노테이션을 통해 스프링 Bean으로 등록합니다.

WebConfig.kt

import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Configuration
class WebConfig : WebMvcConfigurer {

    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**")
            // .allowedOrigins("*") // 모든 origins에 대해 오픈하는것은 보안취약점이 될 수 있으므로 피하자!
                                    // 또한 저렇게 하면 ssl 연동시에 뭔가.. 문제가 발생했었던.. 것.. 같다...
            .allowedOrigins("http://localhost:3003", "https://mydamin.com") // 쉼표를 통해 여러 도메인 등록이 가능
    }
}

위와같이 설정을 추가한 뒤 서버를 재실행 한 뒤,
다시한번 axios를 통한 요청을 날려주면

그림과 같이 서버와 정상적으로 통신이 됨을 확인할 수 있습니다!

profile
성숙해지려고 노력하지 않으면 성숙하기까지 매우 많은 시간이 걸린다.

0개의 댓글