[Spring] newspeed 트러블슈팅

조민경·2025년 2월 20일
0

Spring

목록 보기
3/13

📌 배경

  1. 새로운 서비스에서 사용자 인증 및 인터랙션(좋아요 기능)을 구현해야 했다. 로그인/로그아웃 기능을 통해 사용자 인증을 수행하고, 인증된 사용자만 좋아요를 누를 수 있도록 제한하는 것이 목표였다.

  2. 기존 서비스에서는 사용자의 인증을 위해 세션 기반 인증 방식을 사용하고 있었다. 로그인 시 세션을 생성하고, 이후 요청에서 세션을 활용하여 사용자를 인증하는 구조였다. 그러나 세션 방식은 확장성이 떨어지고, 서버 부하가 증가하는 문제가 있어 JWT(Json Web Token) 기반 인증 방식으로 전환하기로 결정했다.


⚡ 발단

  1. 처음에는 기본적인 로그인 및 로그아웃 로직을 구현하고, 좋아요 기능에서 인증된 사용자만 요청을 처리하도록 해야 했다.
  • 로그인 시 사용자의 이메일과 비밀번호를 검증하고, 성공하면 사용자 정보를 저장하여 이후 요청에서도 인증된 상태를 유지해야 했다.

  • 로그아웃 시에는 사용자의 인증 정보를 삭제하여 보안을 유지해야 했다.

  • 좋아요 기능은 특정 게시물이나 댓글에 대해 사용자가 좋아요를 누르거나 취소할 수 있도록 해야 했다.


  1. 세션 기반 인증을 사용하면 서버가 상태를 유지해야 하므로, 확장성과 유지보수성에 어려움이 있었다. 이에 따라, 상태를 유지하지 않는 JWT를 도입하여 인증 과정을 개선하려 했다.

🔍 전개:

기능을 개발하면서 몇 가지 고민해야 할 점이 있었다.

  1. 로그인 상태 유지 방법:
  • 처음에는 서버에서 세션을 활용했지만, JWT와 같은 토큰을 사용하여 구현했다. 따라서 사용자가 로그인하면 JWT를 발급하고 클라이언트가 이를 저장하도록 했다.


  1. 좋아요 기능에서의 인증 처리:
  • 사용자가 좋아요를 누를 때 인증된 사용자만 가능하도록 해야 했다.

  • HTTP 요청 헤더에서 JWT를 추출하여 인증 정보를 확인하고, 해당 사용자 ID를 기반으로 좋아요 여부를 결정하도록 했다.


  1. 좋아요 중복 처리:
  • 사용자가 같은 게시물이나 댓글에 여러 번 좋아요를 누르는 것을 방지해야 했다.

  • 데이터베이스에서 해당 사용자가 이미 좋아요를 눌렀는지 확인하고, 존재하면 취소하도록 구현했다.


  1. JWT 도입:
  • JWT를 도입하기 위해 기존 로그인, 로그아웃, 좋아요 기능을 변경해야 했다. 로그인 시 JWT를 발급하고, 이후 요청에서 해당 토큰을 검증하여 사용자 정보를 확인하는 방식으로 구현했다. 이 부분은 성준 님께서 수정해주셨다.

  • 로그인 시 사용자의 이메일과 비밀번호를 검증한 후, JWT를 생성하여 클라이언트에 반환하는 방식으로 변경.

  • 좋아요 기능에서는 요청의 헤더에서 JWT를 추출하고, 이를 검증하여 userId를 가져와 처리하도록 변경.

  • 로그아웃은 클라이언트 측에서 토큰을 폐기하는 방식으로 처리.


⚠️ 위기

개발을 진행하면서 몇 가지 예상하지 못한 문제들이 발생했다.

  • 비동기 문제: 좋아요를 동시에 여러 번 누를 경우 중복 요청이 발생할 수 있었다. 이를 해결하기 위해 데이터베이스 @Transactional을 적용했다.

  • JWT 검증 오류: 토큰이 잘못된 경우 401 에러가 발생했으며, 이를 더 직관적인 에러 메시지로 변경하고, 클라이언트에서 재로그인을 유도하도록 수정했다.


🚀 절정

  • 로그아웃 문제는 서버에서 처리할 수 없으므로, 클라이언트 측에서 토큰을 삭제하는 방식으로 안내.

  • 토큰 만료 문제를 해결하기 위해 Refresh Token을 도입하여, Access Token이 만료되었을 때 새로운 토큰을 발급받을 수 있도록 개선.

  • JWT 검증 시 불필요한 데이터베이스 조회를 최소화하고, 토큰을 검증하는 유틸 클래스를 추가하여 성능을 최적화.


🎯 결말

  • 좋아요 기능에서는 중복 요청과 데이터 일관성 문제를 해결하여, 정확한 좋아요 상태를 유지할 수 있도록 개선했다.

  • 인증 방식이 JWT로 전환되면서, 서버에서 별도로 세션을 유지하지 않고도 사용자를 인증할 수 있게 되었다.

  • 확장성이 향상되어, 여러 서버를 운영하는 환경에서도 세션 공유 없이 안정적인 인증이 가능해졌다.

  • Refresh Token을 도입하여 사용자 경험을 개선하였으며, 불필요한 인증 요청을 줄여 서버 부하를 낮추는 효과도 얻었다.

  • 코드 유지보수성이 높아지고, 보안 강화를 위해 토큰 서명 및 만료 시간을 적절히 조정하여 안정적인 운영이 가능해졌다.

  • 로그아웃 시 클라이언트에서 토큰을 삭제하는 방식으로 처리하여, 불필요한 서버 리소스 사용을 줄이고 보안을 강화했다.

  • 결과적으로 로그인/로그아웃 및 좋아요 기능이 안정적으로 동작하며, 확장성과 유지보수성이 향상된 구조로 개선되었다.

0개의 댓글