현재 GigSync라는 인디밴드 커뮤니티 웹 어플리케이션을 개발하고 있다.
로컬 환경에서는 아무 문제 없이 RefreshToken이 쿠키로 잘 전달되고 인증이 매끄럽게 동작했다.
그러나 EC2에 프론트와 백엔드를 각각 배포하면서 문제가 발생했다.
프론트 EC2에서는 로그인 요청을 정상적으로 보내고, 백엔드 EC2에서는 RefreshToken을 Set-Cookie 헤더에 담아 응답했음에도 불구하고, 쿠키가 클라이언트에 저장되지 않았다.
결과적으로 인증 상태가 유지되지 않아 로그인 직후 자동 로그아웃되는 현상이 발생했다.
Same-Origin Policy와 크로스 도메인
브라우저는 보안상 출처(origin)가 다른 경우 쿠키를 자동으로 저장하거나 전송하지 않는다.
항목 | 프론트 | 백엔드 | Same-Origin인가? |
---|---|---|---|
로컬 | http://localhost:5173 | http://localhost:8080 | X (포트 다름) |
EC2 배포 | http://FRONT_IP | http://BACK_IP | X (도메인 다름) |
Set-Cookie의 보안 속성
백엔드가 보낸 쿠키가 브라우저에 저장되려면 아래 조건을 만족해야 한다.
속성 | 설명 | 테스트 환경에서 주의할 점 |
---|---|---|
HttpOnly | 자바스크립트로 접근 불가 | 로그인 보안 향상 |
Secure | HTTPS에서만 동작 | 로컬이나 HTTP EC2에서는 작동 안 함 |
SameSite=None | 크로스 사이트 요청 허용 | Secure 가 반드시 같이 설정되어야 함 |
즉, SameSite=None; Secure 조합은 HTTPS가 아니면 무효하다.
ResponseCookie.from("refreshToken", token)
.httpOnly(true)
.secure(true) // HTTPS 환경에서만 작동
.sameSite("None") // 크로스 도메인 허용
.path("/")
.build();
axios.post('https://api.gigsync.com/login', data, {
withCredentials: true // 반드시 설정
});
체크 항목 | 확인 내용 |
---|---|
withCredentials 설정 여부 | 프론트 axios/fetch에서 반드시 포함 |
Set-Cookie에 SameSite 포함 여부 | 백엔드 쿠키 설정 확인 |
HTTPS 환경 여부 | Secure 쿠키는 HTTPS에서만 유효 |
도메인/서브도메인 설정 | 크로스 도메인 여부에 따라 SameSite 고려 |
테스트 환경에서는 동일 EC2에 프론트와 백엔드를 배치하여 문제를 해결했지만, 서비스 확장성과 보안성을 고려하면 도메인을 이용한 HTTPS 기반의 분리 배포가 필수이다. HttpOnly Cookie 기반 인증은 보안상 유리하지만, 크로스 도메인 환경에서의 제약을 반드시 이해하고 맞춰줘야 한다는 걸 알 수 있었다.