오늘 토큰만료 시 로그인할때 Cookie에 저장해둔 RefreshToken을 통해 토큰을 재발급을 받으려고 했는데
문제가 발생했다 .
우선 로그인 하였을때 쿠키를 집어넣는 코드를 보았을때
◾ AuthService
//로그인 함수{ Cookie refreshTokenCookie = new Cookie("refreshToken",tokenDTO.getRefreshToken()); refreshTokenCookie.setHttpOnly(true); //JS 접근 불가 refreshTokenCookie.setSecure(false); // HTTPS 연결에서만 전송 refreshTokenCookie.setPath("/"); //모든 경로에서 전송 refreshTokenCookie.setMaxAge(7 * 24 * 60 * 60); // 7일 유지 response.addCookie(refreshTokenCookie); }
이렇게 하였을 때 브라우저에서 쿠키의 값을 조회하는 요청을 보내었을때
서버에서는 MissingCookieValueException 가 생긴다.
컨트롤러에서 쿠키의 값을 받는 파라미터는 이렇게 정의하였다.
◾ AuthController
//리프레쉬 토큰 @GetMapping("/getrefresh") public ResponseEntity<?> getRefresh(@CookieValue("refreshToken") String refreshToken) { return authService.getRefresh(refreshToken); }
👉 @CookieValue("refreshToken") : 로그인할때 넣어준 key값으로 쿠키에서 가져온다.
그런데 이 구간에서 가져오지 못하고 MissingCookieValueException 가 발생한것이다..
시도해본 방안들
1. withCredentials: true 설정
우선 axios는 크로스 도메인 요청을 보낼때 쿠키를 자동으로 포함하지 않는다.
따라서 요청 시 쿠키를 포함한다는 설정을 해주어야한다.
getRefresh: async () => {
const result = await axios.get(`${KH_DOMAIN}/auth/getrefresh`, {
withCredentials: true, //쿠키 포함 허용 설정
});
return result.data;
},
그러나 이 방법은 이미 하였던 방법이였기때문에 체크만 하고 넘어갔다.
2. 쿠키 저장 시 Secure , Samesite 설정
Cookie refreshTokenCookie = new Cookie("refreshToken",tokenDTO.getRefreshToken());
refreshTokenCookie.setHttpOnly(true); //JS 접근 불가
refreshTokenCookie.setSecure(false); // HTTPS 연결에서만 전송
refreshTokenCookie.setPath("/"); //모든 경로에서 전송
refreshTokenCookie.setMaxAge(7 * 24 * 60 * 60); // 7일 유지
브라우저에 저장할 쿠키를 담을때 몇가지 설정해두는 것들이 있다.
이중 setSecure 와 Samesite 설정이 있다.
이때 Cookie 객체는 samesite설정을 지원하지 않기때문에 수동 설정을 해줄 경우 직접 setHeader로 넣어주어야한다.
response.setHeader("Set-Cookie",
"refreshToken=" + tokenDTO.getRefreshToken() +
"; Path=/; Max-Age=604800; HttpOnly; SameSite=Lax");
❓ Secure
Secure 속성이 true일 경우 HTTPS 연결에서만 쿠키가 전송된다.
그러나 나는 HTTP 연결을 하고있으므로 false를 해야했다.
❓SameSite
쿠키가 다른 사이트로부터 즉 크로스 도메인으로부터의 요청에도 포함 될 수 있는지를 설정
기본값은 Lax이며 GET요청 등 안전한 도메인에서만 가능하고 none일 경우 모든 요청을 허용한다.
단 none일 경우 secure가 반드시 true여야한다.
따라서
HTTPS 일 경우
👉 Secure : true
👉 SameSite : none
HTTP 일 경우
👉 Secure : false
👉 SameSite : Lax
이렇게 해야한다.
그러나 이 방법도 적용해보았을때 여전히 쿠키가 전송 되지 않았다.
CORS 설정
CORS 설정에서 쿠키를 포함한 요청을 허용하는 설정을 또 할수가있었다.
◾ WebMvcConfig
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:3000") .allowedMethods("GET","POST","PUT","PATCH","DELETE","OPTIONS") .allowedHeaders("*") .allowCredentials(true) //쿠키 포함 허용 .maxAge(MAX_AGE_SECS); ; }
👉.allowCredentials(true) 를 true로 해준다.
◾ AuthController
👉 컨트롤러에도 true로 명시해준다.@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true") public class AuthController {
그래도 다 안된다 .. 😭
원인을 찾던 중 결국 해결했다.
해결❗
로그인 요청에 쿠키 전송을 허용하는 설정을 하지않은것
위에서 쿠키의 값을 가져오기 위해 프론트에서 요청을 보낼때
withCredentials: true 을 설정했었다.
나는 이것을 쿠키의 값만 가져올때만 허용을 해주면 되는 줄 알았는데
쿠키에 값을 저장하고 브라우저로 전송하기 위해서도 허용을 해야한다는것을 몰랐었다.
//로그인
login: async (email, password) => {
const login = {
email: email,
password: password,
};
const result = await axios.post(`${KH_DOMAIN}/auth/login`, login, {
withCredentials: true,
});
return result.data;
},
👉 로그인할때도 쿠키 포함 전송을 허용하는 설정
이 설정을 해주니 쿠키가 브라우저로 들어오는것이 확인되었다 ... 👏👏👏👏👏
'Java' 카테고리의 다른 글
[Java] 지네릭스(Generics) 의 개념과 활용에 대해 알아보기 (2) | 2025.05.14 |
---|---|
[Java] 자바 List에 대해 알아보고 ArrayList와 LinkedList에 차이점을 살펴보기 (2) | 2025.04.02 |
[Java] 자바에서 JDBC를 통해 MySQL를 데이터 조작해보기 (0) | 2025.04.01 |
[Java] 문자열의 묵시적 선언과 명시적 선언에 따른 문자열 비교(Heap (2) | 2025.03.28 |
[Java] 자바 예외 클래스의 계층 구조와 Exception, Error, RuntimeException, IOException 의 차이점을 알아보자 (0) | 2025.03.28 |