[Spring Boot] JWT + Security 인증 및 인가 구현
개인 프로젝트 4주 차 끝나가는 지금 프로젝트 시작하고 일주일 동안 겪었던 상황을 돌이키면서 제일 애먹었던 인증 및 인가 구현 했던 부분에 대해 정리하려고 한다.
❓문제 상황
처음 사용해 보는 Java와 Spring Boot, 그리고 Spring Security... 를 사용한 인증 및 인가 구현이 필요했다.
항해에서 기본 자료를 제공해 줬는데, 그 자료를 보면서 코드를 따라 하는 과정에서 문제가 발생했다.
(지금 돌이켜보면 문제가 아니었을 수도 있고..)
그러나 어디서 문제가 발생한 지 파악이 되지 않고 내가 쓴 코드를 내가 잘 모른다는 상황이 문제 상황이었다.
디버깅도 해보고 코드 하나하나 뜯어보려고 했지만, JWT와 시큐리티 관련 코드들을 한꺼번에 적용시키려다 보니 코드에 대한 이해도 부족했고, 로그인을 했을 때 어떤 식으로 로직이 돌아가는지 파악하기 어려웠다.
일주일 동안 열심히 자료를 찾아보면서 작성한 코드였지만, 이해 없이 코드를 진행한다면 뒤로 갈수록 더 큰 어려움들을 겪을 수 있다고 생각했다. 따라서 그 상황에서 과감히 일주일 동안의 작업을 놓아주고, 먼저 기본적인 CRUD 기능을 작성하고 이후에 인증 부분을 다시 작성하기로 결정했다. 기본적인 기능을 먼저 구현하면서 코드에 대한 이해도를 높이고 나서, 인증 로직을 구현하는 게 중요하다고 판단했다.
💡해결 방법
기본적인 CRUD 기능을 구현하면서 Java와 Spring Boot에 대한 이해도를 높이고 JWT와 Security를 적용했다.
JWT 흐름에 대한 이해
- 인증 요청 시 : 사용자가 입력한 정보를 기반으로 사용자 인증
- 사용자 인증 성공 : JWT 토큰 생성 (사용자 식별 정보, 권한 포함)
- 생성된 토큰 HTTP 응답 헤더에 포함해서 전송
- 클라이언트가 서버에서 요청 보낼 때 토큰을 함께 전송
- 서버에서 토큰 검증 -> 토큰의 서명을 확인, 만료 기간 등을 확인하여 유효성 검사
- 토큰이 유효하면 서버에서 사용자로 인식하고 요청에 대한 작업 수행
사용자가 로그인하면 JwtAuthenticationFilter가 토큰을 추출하고, JwtTokenProvider를 통해 토큰을 생성하거나 검증하며, UserDetailsServiceImpl을 통해 사용자 정보를 가져와 Spring Security의 SecurityContextHolder에 설정한다. 이렇게 설정된 정보를 기반으로 Spring Security가 사용자를 식별하고 권한을 부여하게 된다.
JwtAuthenticationFilter
- 사용자의 HTTP 요청에 대한 필터로, 헤더나 쿠키에서 토큰을 추출
- 해당 토큰을 이용하여 사용자 정보를 가져오고, Spring Security의 SecurityContextHolder에 설정
- 이를 통해 인증된 사용자에게 권한을 부여
JwtTokenProvider
- JWT 토큰을 생성하고 분석
- 사용자 정보를 기반으로 토큰을 생성하고 토큰의 유효성 검증
UserDetailsImpl
- 사용자 정보를 저장하는 Spring Security의 UserDetails 인터페이스를 구현한 클래스
- 사용자의 식별 정보, 비밀번호, 권한 등을 저장하고 반환
UserDetailsServiceImpl
- Spring Security의 UserDetailsService를 구현하여, 사용자의 로그인 정보를 가져오는 역할
- loadUserByUsername 메서드에서 사용자의 이메일(로그인할 때 이메일 사용)을 기반으로 사용자 정보를 조회
SecurityConfig
- Spring Security의 설정을 정의한 클래스로, JwtAuthenticationFilter를 특정 경로에 적용
- 특정 경로에 대한 권한 설정 및 JWT 필터 적용
✨👩💻 ✨
처음엔 남들보다 일주일이 늦는다고 생각해서 조급한 마음이 컸다. 그러나 한 달이 지난 지금 시점에서 봤을 땐 그때의 결정이 내가 한층 더 성장하는데 도움이 됐다. 처음부터 어려운 기능들을 다 써서 적용해야 한다는 생각에 겁먹었지만, 주변사람들의 조언을 듣고 기본적인 기능들을 먼저 구현하고 보니 자신감도 얻고 이해도 높일 수 있었다. 앞으로도 차근차근해나가면 뭐든지 할 수 있을 거 같은 생각도 들었다.(ㅋㅋ)