세션방식
사용자가 로그인하면 서버가 세션을 생성하고 그 ID를 쿠키로 클라이언트에 전달합니다. 이후 요청마다 브라우저가 세션 ID를 서버에 보내면, 서버는 자신의 저장소(메모리, Redis 등)에서 해당 세션을 조회해 인증을 처리합니다.
즉, "누가 로그인했는지"를 서버가 기억하는 구조입니다.
JWT
JWT 로그인 방식
로그인 성공 시 서버가 사용자 정보와 만료시간 등을 담은 토큰을 서명(Signature)해서 클라이언트에게 줍니다. 이후 요청마다 클라이언트가 이 토큰을 Authorization 헤더에 담아 보내면, 서버는 저장소를 조회하지 않고 서명만 검증해서 인증을 처리합니다.
즉 서버가 아무것도 기억하지 않아도 되는 구조입니다.
JWT 구조
JWT는 점으로 구분된 세 파트로 이루어집니다.
JAVASCRIPT1xxxxx.yyyyy.zzzzz 2Header.Payload.Signature
- Header : 토큰 타입(JWT)과 서명 알고리즘(HS256, RS256 등)을 담고 있습니다. Base64Url로 인코딩됩니다.
- Payload : 실제 담고 싶은 데이터(클레임)가 들어갑니다. 사용자 ID, 권한, 만료시간 등입니다. 이것도 Base64Url 인코딩이라 누구나 디코딩해서 볼 수 있습니다. 암호화가 아닙니다.
- Signature : Header + Payload를 서버의 비밀키로 서명한 값입니다. 이 부분 덕분에 위변조 감지가 가능합니다.
Access Token / Refresh Token
실무에서 토큰을 하나만 쓰는 경우는 거의 없습니다. 일반적으로 두 종류의 토큰을 함께 사용합니다.
- Access Token : 수명이 짧습니다. API 요청마다 Authorization 헤더에 담아 보내게 됩니다. 탈취돼도 금방 만료되기 때문에 피해를 줄일 수 있습니다.
- Refresh Token : 수명이 깁니다. Access Token이 만료되었을 때 재발급받는 용도로만 사용합니다. 보통 HttpOnly 쿠키에 저장합니다.