JWT 인증 방식이란?
기존 세션 방식은 서버에 로그인 정보를 저장한다. JWT는 토큰에 사용자 정보를 담아서 클라이언트가 직접 들고 다니는 방식이다. 서버는 상태를 저장하지 않으니까 매 요청마다 토큰만 검증하면 된다.
전체 흐름
1. 로그인 요청 (username, password)
↓
2. 인증 성공 시 JWT 토큰 발급
↓
3. 클라이언트는 이후 요청마다 토큰을 헤더에 담아 전송
Authorization: Bearer {token}
↓
4. 서버는 필터에서 토큰 검증 후 인증 처리
↓
5. 컨트롤러 접근
흐름 자체는 단순한데, 이게 여러 클래스에 나눠져 있어서 처음엔 뭐가 뭔지 몰랐다.
주요 구성 요소
JwtTokenProvider
토큰 생성, 검증, 사용자 정보 추출 담당이다. 비밀키로 서명해서 위변조를 막는다.
주요 메서드는 createToken(), validateToken(), getUsername() 이렇게 세 개다.
JwtAuthenticationFilter
매 요청마다 실행되는 필터다. Authorization 헤더에서 토큰을 꺼내서 검증하고 유효하면 SecurityContext에 인증 정보를 넣어준다. 이게 있어야 이후 요청에서 인증된 사용자로 처리된다.
SecurityConfig
Spring Security 전체 설정이다. CSRF 비활성화, 세션 STATELESS, URL별 접근 권한을 여기서 잡는다.
/api/auth/**는 누구나 접근 가능하고 나머지는 인증 필요하다. JWT 필터도 여기서 체인에 추가한다.
이 설정 처음 건드렸을 때 전부 막히거나 전부 뚫리거나 둘 중 하나였다. 뭘 어디서 설정해야 하는지 잘 모르겠어서 엄청 해맸다.
AuthController
로그인 엔드포인트 제공이다. AuthenticationManager로 인증 처리하고 성공하면 토큰 발근급해서 반환한다.
보안 고려사항
- JWT secret은 환경변수로 관리 (코드에 직접 쓰면 안 됨)
- HTTPS 필수
- 토큰 만료 시간 설정 (보통 1시간~1일)
- Refresh Token 추가 구현 고려
느낀 점
처음엔 필터, SecurityContext, Authentication 개념이 한꺼번에 나와서 어디서부터 봐야 할지 몰랐다.
SecurityConfig 설정 하나 잘못 건드렸다가 모든 요청이 막혀버려서 당황 했던적도 있었다.
결국 핵심은 토큰을 어떻게 만들 어떻게 검증하느냐였다.
이걸 중심으로 각 클래스 역할을 따라가니까 그래도 조금은 흐름이 이해가 됐다.