세션으로 현재 사용자 조회하기

배경

기존 프론트는 현재 사용자 정보를 브라우저 저장소에 저장해서 사용했다. 하지만 브라우저 저장소는 JavaScript로 접근할 수 있기 때문에 XSS 공격에 취약하다.

이번 미션에서는 사용자 정보를 브라우저 저장소가 아니라 서버 세션 기준으로 관리하도록 바꾸었다.

세션과 JSESSIONID

HTTP 요청은 기본적으로 상태를 기억하지 않는다. 그래서 서버는 사용자가 이전 요청에서 로그인했는지 알 수 없다.

로그인에 성공하면 서버는 세션을 만들고 브라우저에 JSESSIONID 쿠키를 내려준다. 브라우저는 이후 요청마다 이 쿠키를 보내고, 서버는 그 값으로 세션을 찾는다.

현재 사용자 조회 API

현재 사용자 조회 API는 다음과 같다.

GET /api/auth/me

이 API는 세션에 저장된 인증 정보를 기준으로 현재 로그인한 사용자의 UserDto를 반환한다.

핵심 파일

  • AuthController
  • DiscodeitUserDetails
  • SecurityConfig
  • BasicUserService

AuthController에서는 @AuthenticationPrincipal을 사용해 현재 로그인한 사용자 정보를 받는다.

요청 흐름

브라우저
  ↓
GET /api/auth/me
  ↓
JSESSIONID 쿠키 전송
  ↓
Spring Security가 세션에서 인증 정보 조회
  ↓
@AuthenticationPrincipal에 DiscodeitUserDetails 주입
  ↓
UserDto 응답

로그인하지 않은 상태라면 인증 정보가 없기 때문에 401이 발생한다.

왜 다시 조회했을까

principal 안의 UserDto는 로그인 당시 정보일 수 있다. 권한이나 온라인 상태가 바뀌었을 수도 있다.

그래서 /api/auth/me에서는 principal의 사용자 ID를 기준으로 UserService.find를 다시 호출해 최신 상태에 가까운 UserDto를 반환하도록 했다.

PR에서 설명할 말

현재 사용자 조회를 브라우저 저장소가 아니라 Spring Security 세션 기반으로 변경했다. GET /api/auth/me에서 @AuthenticationPrincipal로 인증 사용자를 받고, 사용자 ID 기준으로 최신 UserDto를 조회해 반환하도록 구성했다.

배운 점

JSESSIONID는 로그인 정보를 직접 담고 있는 쿠키가 아니라, 서버의 세션을 찾기 위한 열쇠다. 실제 인증 정보는 서버 쪽 세션과 SecurityContext에 연결되어 있다.