새로운 서비스에서 사용자 인증 및 인터랙션(좋아요 기능)을 구현해야 했다. 로그인/로그아웃 기능을 통해 사용자 인증을 수행하고, 인증된 사용자만 좋아요를 누를 수 있도록 제한하는 것이 목표였다.
기존 서비스에서는 사용자의 인증을 위해 세션 기반 인증 방식을 사용하고 있었다. 로그인 시 세션을 생성하고, 이후 요청에서 세션을 활용하여 사용자를 인증하는 구조였다. 그러나 세션 방식은 확장성이 떨어지고, 서버 부하가 증가하는 문제가 있어 JWT(Json Web Token) 기반 인증 방식으로 전환하기로 결정했다.
로그인 시 사용자의 이메일과 비밀번호를 검증하고, 성공하면 사용자 정보를 저장하여 이후 요청에서도 인증된 상태를 유지해야 했다.
로그아웃 시에는 사용자의 인증 정보를 삭제하여 보안을 유지해야 했다.
좋아요 기능은 특정 게시물이나 댓글에 대해 사용자가 좋아요를 누르거나 취소할 수 있도록 해야 했다.
기능을 개발하면서 몇 가지 고민해야 할 점이 있었다.
처음에는 서버에서 세션을 활용했지만, JWT와 같은 토큰을 사용하여 구현했다. 따라서 사용자가 로그인하면 JWT를 발급하고 클라이언트가 이를 저장하도록 했다.
사용자가 좋아요를 누를 때 인증된 사용자만 가능하도록 해야 했다.
HTTP 요청 헤더에서 JWT를 추출하여 인증 정보를 확인하고, 해당 사용자 ID를 기반으로 좋아요 여부를 결정하도록 했다.
사용자가 같은 게시물이나 댓글에 여러 번 좋아요를 누르는 것을 방지해야 했다.
데이터베이스에서 해당 사용자가 이미 좋아요를 눌렀는지 확인하고, 존재하면 취소하도록 구현했다.
JWT를 도입하기 위해 기존 로그인, 로그아웃, 좋아요 기능을 변경해야 했다. 로그인 시 JWT를 발급하고, 이후 요청에서 해당 토큰을 검증하여 사용자 정보를 확인하는 방식으로 구현했다. 이 부분은 성준 님께서 수정해주셨다.
로그인 시 사용자의 이메일과 비밀번호를 검증한 후, JWT를 생성하여 클라이언트에 반환하는 방식으로 변경.
좋아요 기능에서는 요청의 헤더에서 JWT를 추출하고, 이를 검증하여 userId를 가져와 처리하도록 변경.
로그아웃은 클라이언트 측에서 토큰을 폐기하는 방식으로 처리.
개발을 진행하면서 몇 가지 예상하지 못한 문제들이 발생했다.
비동기 문제: 좋아요를 동시에 여러 번 누를 경우 중복 요청이 발생할 수 있었다. 이를 해결하기 위해 데이터베이스 @Transactional
을 적용했다.
JWT 검증 오류: 토큰이 잘못된 경우 401 에러가 발생했으며, 이를 더 직관적인 에러 메시지로 변경하고, 클라이언트에서 재로그인을 유도하도록 수정했다.
로그아웃 문제는 서버에서 처리할 수 없으므로, 클라이언트 측에서 토큰을 삭제하는 방식으로 안내.
토큰 만료 문제를 해결하기 위해 Refresh Token
을 도입하여, Access Token
이 만료되었을 때 새로운 토큰을 발급받을 수 있도록 개선.
JWT 검증 시 불필요한 데이터베이스 조회를 최소화하고, 토큰을 검증하는 유틸 클래스를 추가하여 성능을 최적화.
좋아요 기능에서는 중복 요청과 데이터 일관성 문제를 해결하여, 정확한 좋아요 상태를 유지할 수 있도록 개선했다.
인증 방식이 JWT로 전환되면서, 서버에서 별도로 세션을 유지하지 않고도 사용자를 인증할 수 있게 되었다.
확장성이 향상되어, 여러 서버를 운영하는 환경에서도 세션 공유 없이 안정적인 인증이 가능해졌다.
Refresh Token을 도입하여 사용자 경험을 개선하였으며, 불필요한 인증 요청을 줄여 서버 부하를 낮추는 효과도 얻었다.
코드 유지보수성이 높아지고, 보안 강화를 위해 토큰 서명 및 만료 시간을 적절히 조정하여 안정적인 운영이 가능해졌다.
로그아웃 시 클라이언트에서 토큰을 삭제하는 방식으로 처리하여, 불필요한 서버 리소스 사용을 줄이고 보안을 강화했다.
결과적으로 로그인/로그아웃 및 좋아요 기능이 안정적으로 동작하며, 확장성과 유지보수성이 향상된 구조로 개선되었다.