티스토리 뷰

현재 진행하고 있는 프로젝트에서 리프레시 토큰은 쿠키에, 액세스 토큰은 헤더에 담아서 통신을 하기로 했다. 얼마 전, 리프레시 토큰 구현을 마치고 로그인 시, 쿠키를 함께 반환하도록 기능을 구현했다. 그러나 이 과정에서 예상치 못한 오류들이 나왔다.

 

🍪 수정 전 쿠키 관련 세팅

private Cookie createCookie(TokenResponseDto tokenResponseDto) throws UnsupportedEncodingException {
        Cookie cookie = new Cookie(JwtTokenProvider.REFRESH_TOKEN_HEADER_STRING, tokenResponseDto.getRefreshToken());
        cookie.setMaxAge(Math.toIntExact(cookieValidTime));
        cookie.setHttpOnly(true);
        cookie.setPath("/");
        return cookie;
    }
response.addCookie(createCookie(tokenResponseDto)); // 쿠키 등록시


수정 전, 쿠키 관련 세팅은 위와 같았다.

key 는 RefreshToken, value 는 dto 에서 가져온 리프레시 토큰이었다.

setMaxAge 는 유효기간, setHttpOnly 는 보안상의 이유로 http 방식으로만 쿠키의 접근을 허용하는 것이다. setPath 는 쿠키가 적용될 url 의 path 를 지정한다.

 

🍭 HttpOnly 는 왜 필요할까?

쿠키는 클라이언트에서 조회되기 때문에 해커들은 이를 노린다. 따라서 Http 요청으로만 이에 접근할 수 있고, 브라우저에서는 이를 접근할 수 없도록 하는 것이다.

https://nsinc.tistory.com/121

 

[Web] HTTP Only와 Secure Cookie 이해하기

Cookie에 대한 이해 쿠키는 ASP.NET, PHP와 같은 특정 기술영역에 국한된 것도 아니고, 특정 Client나 Server에만 국한된 기술도 아닙니다. 쿠키는 수십 년 전부터 사용되어 왔으며 최근에는 HTTP에 있어서

nsinc.tistory.com

 

🍪 첫번째 오류 samesite

첫번째로 통신시 발생했던 오류는 samesite 였다. 이는 크롬 정책에 따른 오류로, 서로 다른 도메인에서 호출한 경우에는 브라우저에서 쿠키에 대한 설정을 막는다. 나의 프로젝트의 경우, 클라이언트와 서버의 도메인이 달랐기 때문에 이를 막은 것으로 보인다.

기본적으로 lax 로 되어있기 때문인데, 이를 None 으로 변경하면 해당 오류를 해결할 수 있다. 그러나 이 세팅을 위해서는 상단의 코드를 많이 바꿔야 했다.

https://kindloveit.tistory.com/100

 

[Spring boot] Chrome Cookie SameSite 해결하기

보통 Backend 에서 사용자 인증을 완료하고 Token 전달의 수단으로 Cookie를 많이 사용한다. Backend 로직에서 브라우저 Cookie 저장을 위해서 다음과 같이 보통 설정을 하게 된다. package com.deeplify.tutorial.o

kindloveit.tistory.com

 

 private ResponseCookie createCookie(TokenResponseDto tokenResponseDto) throws UnsupportedEncodingException {
        return ResponseCookie.from(JwtTokenProvider.REFRESH_TOKEN_HEADER_STRING, tokenResponseDto.getRefreshToken())
                .path("/").sameSite("None").secure(true).maxAge(Math.toIntExact(cookieValidTime)).httpOnly(true)
                .build();}
response.addHeader("Set-Cookie", createCookie(tokenResponseDto).toString()); // 쿠키 등록

 

기존의 cookie 에는 samesite 관련 세팅을 할 수 없다. 따라서 스프링에서 제공하는 ResponseCookie 를 사용했다.

또한, 헤더에 등록하는 것이기에 string 으로 형변환을 하여 담아줬다.

 

🍭 ResponseCookie 는 무엇일까?

스프링에서 제공하는 쿠키이다. 이는 헤더의 set-cookie 에 원하는 속성을 추가할 수 있다.

 

🍪 두번째 오류 cors

cors 오류가 나지 않다가 쿠키를 적용하자 발생한다고 알려주셔서 cors 세팅을 다시 훑어봤다.

쿠키 + cors 키워드로 구글링을 하니 credentials 라는 답을 알게 되었다.

 

🍭 crendetials 는 무엇일까?

쿠키, 인증헤더, TLS client certificates(증명서) 를 의미한다. 이를 true 로 둔다는 것은 credentials 를 사용하겠다는 의미이다. 

 

🍭 cors의 crendetials 는 무엇일까?

기본적으로 호출은 쿠키가 없이 이루어진다. (credentials 가 false 로 되어있다.) 그러나, 클라이언트가 요청을 보내기 전에 withCredentials 가 true 로 되어 있지 않으면 다른 도메인에 대한 쿠키값의 설정이 불가능하다. 따라서 이를 true 로 두게 되면 클라이언트와 서버가 쿠키값을 공유할 수 있게 된다.

 

🍭 클라이언트는 요청을 두번 보내나?

관련 구글링을 하다가 options, preflighted 라는 단어들을 계속 마주치게 되어 찾아봤다.

 

🍭 preflighted 란?

브라우저의 요청이 안전한지 확인하기 위해서 브라우저가 본 요청을 보내기 전에 OPTIONS 메서드로 요청을 미리 한번 보내는 방식이라고 한다. 즉, preflighted 시에 withCredentials 가 true 가 아니었기에 cors 에러가 난 것임을 알 수 있었다.

 

https://wonit.tistory.com/571

 

[HTTP] OPTIONS 헤더와 Preflight 그리고 CORS

OPTIONS 는 RFC 7231 에 명시된 HTTP의 여러 메서드 중 하나이다. OPTIONS 는 실제로 우리가 프레임워크나 라이브러리를 사용한다면 직접 사용할 일은 드물지만 현대의 Front Back 을 나누는 개발 흐름에서

wonit.tistory.com

https://basemenks.tistory.com/246

 

Credentials 과 쿠키에 대해서

Credentials (인증서) Credentials 이란 쿠키, 인증헤더, TLS client certificates(증명서)를 말한다. Credentials 이 있는 CORS 요청은 Client와 Server 둘다 Credentials를 사용하겠다는 속성을 설정해줘야 통신이 가능하

basemenks.tistory.com

 

🍭 수정 이후 코드

 @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://localhost:3000", "클라이언트 서버", "클라이언트 서버")
                .allowedHeaders("*").allowedMethods("*").allowCredentials(true);
    }

기존에는 origins 에 * 로 해뒀었는데 credentials 를 허용하면 origins 를 직접 세팅해줘야 한다고 했고, 보안상 좋지도 않기에 수정했다. 

 

 

 

이렇게 수정해줬더니 통신에 성공~! Set-Cookie 가 잘 넘어오는 모습을 확인할 수 있었다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함