본문 바로가기
Spring/Spring Security

토큰기반 인증, JWT

by doriver 2024. 11. 4.

쿠키와 세션을 이용한 로그인 구현은

세션을 서버에 저장해야하므로 비효율적, 서버 확장 시 서버간에 세션을 공유하기 어렵다.
 > 이러한 단점을 해결하기 위한 방법으로 토큰 기반의 인증 방법을 사용할수 있다.

 

토큰기반 인증
로그인 이후 서버가 토큰( 사용자 정보가 암호화 되어있는 문자열 )을 만들어서 사용자에게 넘겨준다. 이 토큰을 이용하여 인증된 사용자인지 서버가 판단함

 

JWT( JSON Web Tocken )

인증에 필요한 정보들을 암호화 시킨 JSON 토큰
JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것( 일반적인 Base64 Encode를 URL에서 오류 없이 사용하도록 '+'와 '/'를 각각 '-', '_'으로 표현한 것 )
토큰 내부에는 개인키를 통한 전자서명이 들어있다.

 

JWT를 이용한 인증

Token기반으로 유저를 인증하고 식별

토큰 자체에 사용자의 정보들이 포함되어 있다는 점(Self-contained)이 특징

서버가 클라이언트의 상태를 저장하지 않아도 되기 때문에 Stateless하게 설계가 가능

3,4. 서버에서 서명된(Signed) JWT 토큰을 생성하여 클라이언트에 응답으로 반환
5. 클라이언트는 응답으로 반환된 JWT토큰으로 요청 시 마다 Http Header에 JWT를 담아 요청
6,7. 요청의Http Header의 JWT를 검증하여 토큰이 유효하다면 요청에 맞는 응답 반환

 

AccessToken + RefreshToken

탈취 위험
만약, 해커가 JWT AccessToken을 탈취한다면? 해커는 탈취한 AccessToken을 사용하여 접근 가능
이를 해결하기 위해

, AccessToken의 유효 기간을 짧게 + RefreshToken으로 AccessToken을 재발급

 

1. AccessToken 
처음 로그인 요청 시 서버에서 실제 유저의 정보가 담긴 AccessToken을 발행합니다.
클라이언트는 이 AccessToken을 저장한 후, 요청마다 AccessToken담아서 보냄
해당 AccessToken을 서버에서 검증 후 유효하면 요청에 맞는 응답을 진행

2. RefreshToken
처음 로그인 요청 시 서버에서 AccessToken 재발급 용도인 RefreshToken을 발행
이때, 클라이언트는 RefreshToken을 저장하지 않고 RefreshToken은 보통 서버 DB에 저장
RefreshToken이 유효하면, AccessToken의 재발급을 진행


AccessToken이 시간이 지나 만료 후 클라이언트가 요청을 보낼 때, RefreshToken로직이 추가되면

서버에서는 인증 실패가 아닌 RefreshToken검증 단계에 진입
RefreshToken이 유효하다면, 그 즉시 클라이언트에게 새로운 AccessToken을 발행
사용자의 눈에는 별도의 재로그인 과정없이 AccessToken이 만료되지 않은 것처럼 동작

 

JWT의 구조

각각의 구성 요소( Header, Payload, Signature )가 . 으로 구분

1. Header에는 보통 토큰의 타입이나, 전자서명 시 어떤 알고리즘이 사용되었는지 저장
2. Payload

보통 Claim( key-value 형식으로 이루어진 하나의 쌍들 )이라는 인증 시에 실제로 사용될 정보들이 담겨있다.
암호화가 되어 있지 않기 때문에, 민감한 정보를 담지 않아야 함

 

3. JWT 구조에서 가장 중요한 Signature(서명)

 

JWT 검증 과정

1. 클라이언트가 서버에 요청 시 JWT토큰을 Http Header에 담아 요청합니다.
2. 서버에서 Http Header의 JWT 토큰을 꺼내서 가져옵니다.
3. 클라이언트가 요청한 JWT토큰을 서버가 가지고 있는 개인키를 가지고 Signature를 복호화합니다.
4. 복호화한 Signature의 base64UrlEncode(header)/base64UrlEncode(payload)가

각각 요청한 JWT토큰의 header, payload와 일치하는지 검증합니다.
5. 일치한다면 인증을 허용하고, 일치하지 않는다면 인증이 실패합니다.