현재 진행 중인 프로젝트의 로그인 기능은 토큰을 사용한다.
해당 토큰은 만료일이 존재하기 때문에 시간 관리가 굉장히 중요한데,
시간이 맞지 않으면, 토큰이 항상 만료 상태일 위험이 있기 때문이다.
처음에 RDS와 EC2 Server는 시간이 UTC
로 되어 있어서,
Amazon에서 직접 Parameter group을 설정해서 시간을 맞추고
터미널에서도 EC2에 SSH Protocol로 접속을 해서 서버 시간을 맞추었다.
기본 시간이 UTC
이기 때문에 모두 Asia/Seoul
로 맞추었는데,
문제는 Postman의 응답에서 출력되는 만료 시간이었다.
분명 DB에서 select now()
도 해보고 서버 시간을 확인해봐도,
모두 Asia/Seoul
로 현재 우리나라의 시간과 동일하게 출력 됐다.
하지만, 아래 생성된 토큰의 만료 일자를 확인해보면 9시간 차이가 남을 알 수 있다.
UTC
세계 표준시는 우리나라 보다 9시간 빠른 시간이므로,
UTC
` 임을 알 수 있다.
RDS와 EC2는 모두 설정을 해놓았으니, 의심해볼 것은 Spring Project 뿐이다.
조금 찾아보니, @PostConstruct
를 통해 Timezone
을 설정하는 방법이 있다고 한다.
해당 방법을 적용해 아래와 같이 코드를 작성했다.
하지만 결과는 실패. 아직 시간이 제대로 바뀌지 않았다.
아래와 같이 로그를 찍어보니, Spring Project도 Asia/Seoul
시간인 듯 하다.
그럼 도대체 뭐가 문제라서 결과 시간은 ```UTC``로 뜨는 것일까?
그래서 Postman의 Response Header를 한번 살펴보았다.
Response Header에 Date
항목이 현재 GMT(UTC)
임을 볼 수 있다.
해당 응답은 서버에서 날아오는 것일텐데, 그럼 서버 시간이 문제일까?
위에서 확인한 서버 시간은 분명히 KST
한국 시간으로 설정되어 있었다.
기능 동작도 다 제대로 되는데, 왜 Postman 응답만 이런 것일까?
HTTP의 공식 문서인 RFC9110 과 Mozilla에서 제공하는 MDN 을 보니,
Date
Header는 기본적으로 GMT(UTC)
를 사용한다고 한다.
이 정보와는 딱히 연관이 없을 것 같다.
분명 나는 Date 객체를 담아서 JSON Response로 출력해주는 기능을 만들었는데,
Postman에는 왜 내가 담은 대로 출력이 안되고 UTC
로 출력할까?
조금 더 찾아보니, JSON으로 변환하는 과정에서 아무래도 문제가 있는 것 같았다.
응답 시, Jackson
의 ObjectMapper
가 동작해서 DTO
를 Json으로 직렬화 하는데,
이 때 _serializationConfig
의 기본 설정이 UTC 라고 한다.
이는 Jackson
라이브러리의 기본 값이며, 2.7 version 부터 그래왔다고 한다.
@JsonFormat
Annotation을 사용하는 경우 Timezone을 지정할 수 있다고 한다.
이 방식을 이용하니 아래와 같이 제대로 출력된다!
제대로 동작을 하게 되었으니 다행이다.
찾은 정보가 쓸모는 없었지만 공식문서를 찾아보는 경험치는 +1 된 것 같은 기분이다.
참고문헌
MDN HTTP : Date
RFC 9110 HTTP : Date/Time Formats
Shane’s planet