Error - cookie 역직렬화 문제

topics 300-백엔드개발 307 인증 & 보안
types 에러해결
tags #cookie #serialization #spring-security

Cookie 역직렬화 문제

쿠키에 객체 저장했다가 읽을 때 역직렬화 실패하는 경우.

상황

Spring Security에서 OAuth2 인증 후 쿠키에서 AuthorizationRequest 읽으려다 에러 발생.

java.io.InvalidClassException: ... local class incompatible:
stream classdesc serialVersionUID = xxx, local class serialVersionUID = yyy

or

SerializationException: Failed to deserialize object

왜 발생할까

1. 클래스 변경됨

배포하면서 클래스 구조가 바뀌면 기존 쿠키의 직렬화된 데이터와 호환 안 됨.

2. serialVersionUID 없음

public class MySession implements Serializable {
    // serialVersionUID 없으면 클래스 바뀔 때마다 자동 생성됨
    private String data;
}

3. 쿠키 인코딩 문제

Base64 인코딩/디코딩 과정에서 깨지는 경우.

해결 방법

1. serialVersionUID 명시

public class MySession implements Serializable {
    private static final long serialVersionUID = 1L;
    private String data;
}

왜 이렇게 했냐면: 명시적으로 버전 관리하면 클래스 변경해도 호환성 유지 가능.

2. 쿠키 대신 세션 또는 DB 사용

쿠키에 객체 저장하는 건 사실 안티패턴임.

// 쿠키엔 ID만
Cookie cookie = new Cookie("sessionId", UUID.randomUUID().toString());

// 실제 데이터는 Redis나 DB에
redisTemplate.opsForValue().set(sessionId, authRequest, Duration.ofMinutes(10));

3. JSON으로 저장

직렬화 대신 JSON 사용하면 버전 문제 줄어듦.

// 저장
String json = objectMapper.writeValueAsString(authRequest);
String encoded = Base64.getUrlEncoder().encodeToString(json.getBytes());
Cookie cookie = new Cookie("auth", encoded);

// 읽기
String decoded = new String(Base64.getUrlDecoder().decode(cookieValue));
AuthRequest request = objectMapper.readValue(decoded, AuthRequest.class);

4. Spring Security OAuth2 쿠키 문제

HttpCookieOAuth2AuthorizationRequestRepository 쓸 때 자주 발생.

@Bean
public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository() {
    // 기본 구현 대신 커스텀
    return new CustomCookieAuthorizationRequestRepository();
}

삽질 포인트

배포 후에만 에러 터지고 로컬에선 재현 안 됨.

2시간 삽질한 끝에 알아낸 것: 이전 버전 앱에서 생성한 쿠키가 브라우저에 남아있어서 그럼.

해결:

  • 쿠키 이름 버전 붙이기: auth_v2
  • 또는 쿠키 만료시간 짧게

결론

  • 쿠키에 복잡한 객체 저장하지 마라
  • 저장해야 하면 JSON 사용
  • serialVersionUID 꼭 명시
  • 배포 시 기존 쿠키 무효화 고려