CORS설정과 withCredentials 속성

HGY·2023년 10월 23일

JWT 구현하기

목록 보기
3/3

React에서 axios 요청을 할 때 그냥 하면 쿠키를 받을 수 없다
CORS 설정과 withCredentials 속성을 사용해야 한다.

withCredentials? 그게 뭔데

withCredentials 옵션은 단어의 의미에서 알 수 있듯이, 서로 다른 도메인(크로스 도메인)에 요청을 보낼 때 요청에 credential 정보를 담아서 보낼 지를 결정하는 항목이다.

여기서, credential 정보가 포함되어 있는 요청은 아래 두 가지 경우를 의미한다.

  1. 쿠키를 첨부해서 보내는 요청
  2. 헤더에 Authorization 항목이 있는 요청

따라서, 보내고자 하는 요청이 위 두 가지 항목 중 한 가지라도 포함하고 있다면 withCredentials 옵션을 true로 설정해야만 한다.

클라이언트 요청 설정

// 전역적으로 선언하기
axios.defaults.withCredentials = true; // withCredentials 전역 설정

// axios 옵션으로 설정하기
axios.post(
    'https://localhost:8080/auth/login', 
    { profile: { username: username, password: password } }, 
    { withCredentials: true }
).then(res => { 
    console.log(res); 
    console.log(res.data); 
})

서버 응답 설정

한편, credential 정보가 포함되어 있는 요청이 정상적으로 처리되기 위해서는 해당 요청을 받는 서버 측에서도 다음과 같은 설정이 필요하다.

  1. 응답 헤더의 Access-Control-Allow-Credentials 항목을 true로 설정해야 한다..
  2. 응답 헤더의 Access-Control-Allow-Origin의 값이 반드시 설정되어야 합니다. 단 와일드카드 문자("*")는 사용할 수 없다.
  3. 응답 헤더의 Access-Control-Allow-Methods의 값을 지정해야 할 경우 와일드카드 문자("*")는 사용할 수 없다.
  4. 응답 헤더의 Access-Control-Allow-Headers의 값을 지정해야 할 경우 와일드카드 문자("*")는 사용할 수 없다.

유의해야 할 점은 Access-Control-Allow-* 헤더 값들을 지정해야 하는 경우에는, 와일드카드 문자를 제외한 값으로 설정되어야 한다는 것이다.

이 값이 와일드카드 문자로 설정될 경우, 요청에 대한 응답이 클라이언트로 전해지기는 하지만 클라이언트 js에서는 이 응답에 접근을 할 수 없는 상태가 된다. 브라우저가 이를 차단하고 있기 때문이다. 이는 브라우저 개발자도구에서 자주 볼 수 있는 CORS Error가 표시되는 이유 중 한 가지이기도 하다.

//스프링 서버 전역적으로 CORS 설정
@Configuration
public class WebConfig implements WebMvcConfigurer {
	@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        	.allowedOrigins("https://localhost:8090") // 허용할 출처
            .allowedMethods("GET", "POST") // 허용할 HTTP method
            .allowCredentials(true) // 쿠키 인증 요청 허용
            .maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
    }
}

Spring 쿠키 생성

TokenDto jwt = authService.login(memberRequestDto);

Cookie cookie1 = new Cookie("AccessToken", jwt.getAccessToken());
cookie1.setPath("/");
cookie1.sameSite("None");
cookie1.setDomain("localhost");
cookie1.setHttpOnly(true);
cookie1.setSecure(true);

response.addCookie(cookie1);
profile
바보 개발자 지망생

0개의 댓글