- 사용자가 인증정보(예:아이디, 비밀번호)를 이용하여 웹 애플리케이션에 로그인 요청을 보낸다.
- 서버는 사용자의 인증정보(예:아이디, 비밀번호)를 검증한다.
- 인증에 성공하면, 서버는 로그인된 사용자 정보와 서버의 Private key를 이용하여 JWT를 생성한다.
- 서버는 생성된 JWT토큰을 클라이언트에게 전송한다.
- 일반적으로 서버는 Blacklisting, 재사용 등과 같은 특별한 목적 이외에는 자신이 발행한 JWT토큰을 별도로 저장하지 않는다.
- 그러나 클라이언트는 서버가 전송한 JWT를 사용해야 하기 때문에 브라우저의 쿠키, 세션스토리지, 로컬스토리지 등 안전한 저장소와 방법으로 JWT를 저장한다.
- 클라이언트는 서버에게 어떤 요청을 보낼때, 자신이 저장하고 있는 JWT를 HTTP헤더에 포함시켜 서버에 전송한다.
- 대부분 “Authorization”, “WWW-Authenticate”헤더 변수에 “Bearer [토큰]” 형태로 전송한다.
- 서버는 클라이언트의 요청시 HTTP헤더에 있는 JWT를 검증하는데, 이 과정에서 서버의 Private key로 Signature 부분을 확인하여 자신이 발행한 JWT가 맞는지 검증한다.
- JWT의 Signature 검증결과가 유효하면 Payload부분을 해독하여 클라이언트의 정보를 확인할 수 있다.
- 이렇게 서버는 클라이언트를 식별하고 해당 클라이언트의 권한에 따라 요청을 처리한다.
- 또한, JWT에 설정된 토큰 만료시간 “exp”값 또는 Blacklist 존재 여부를 확인하여 클라이언트가 보낸 JWT토큰의 유효성 여부도 검증을 한다.
- JWT토큰이 만료시기가 도래하면 클라이언트는 “Refresh Token”과 같은 메커니즘을 통해 새로운 JWT를 발급 받을 수 있다.
- 전통적인 Session 처럼 생성부터 폐기까지의 Lifecycle을 생각하면 JWT토큰방식은 서버에 저장하지 않고 클라이언트에 저장하는 방식이기 때문에 서버에서 폐기단계를 구현하는 것이 없다.
- 그러나 이런 기능을 대신하는 것이 “exp”설정과 Token Blacklisting 기능을 구현하는 것이다.
- Blacklisting 기능구현을 위해 Redis와 같은 메모리 데이터베이스를 사용하는 것이 일반적인데, 모든 Token을 생성할 때 마다 Redis에 저장하고 있다가 폐기하는 기능을 구현할 수는 있으나 이 방법은 JWT를 이용하는 목적과는 상반되는 방법이기 때문에 추천하지 않는 방법이다.
- 따라서, “exp”를 이용한 Token만료기간 설정과 Blacklisting 기능을 이용하여 만료되거나 또는 로그아웃 등으로 유효하지 않은 JWT Token이 악의적 사용자에게 악용되지 않도록 해야 한다.