JWT 토큰과 무상태성(Stateless)

Sheryl Yun·2021년 12월 15일
5

토큰 기반 인증은 서버의 무상태성(Stateless)를 유지하기 위한 시스템이다.
JWT 토큰을 보기 전에 먼저 무상태성에 대해 얘기해보자.

** 추가: https://han-um.tistory.com/17

무상태성

출처: https://www.notion.so/HTTP-80593ee053bb4186a42c7c62446f12a2?p=6d6e1b6827c748298de7578b58f361de

무상태성이란 서버가 클라이언트의 상태를 보존하지 않음을 의미한다.

서버는 클라이언트를 기억하지 않으며
오직 클라이언트의 요청에 대한 응답만 준다.

HTTP 통신은 기본적으로 무상태성(Stateless)을 지향한다.
왜냐하면 서버를 무한 확장 가능하기 때문이다.
=> 고객이나 요청(트래픽)이 갑자기 증가할 때 서버를 추가하기 쉬워진다.

만약 서버가 stateful하다면, 서버 하나가 장애가 났을 때
그 서버와 연결된 클라이언트가 기존 작업을 처음부터 다시 해야 하는 상황이 발생한다. (예: 사이트 튕기면 결제를 처음부터 다시 해야 하는 것)

그러나 서버가 stateless하다면, 클라이언트 쪽에서 고객의 정보를 보관하므로 한 서버에서 장애가 나도 다른 서버에서 얼마든지 이후 요청을 처리할 수 있다.

무상태성의 단점은 클라이언트가 서버한테 요청할 때 추가로 전송해야 할 정보가 늘어난다는 것이다. (예: JWT 토큰)

이렇게 하면 요청/응답 시 오가는 payload가 커질 수 있다.
따라서, 모든 경우를 무상태성으로 설계하지는 않는다.

예: 로그인이 필요없는 단순 서비스 소개 화면, 로그인한 상태를 유지하기 위해 세션스토리지 사용 시

JSON 토큰

출처: https://velog.io/@heumheum2/JWT-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D
출처: https://naon.me/posts/til63

JSON 토큰은 JSON Web Token의 약자로, JSON 객체를 사용하여 클라이언트와 서버 사이에 정보를 안전성 있게 전달해준다. 회원가입, 로그인 등 사용자 인증 관련 작업에 사용된다.
클라이언트에는 토큰만을 저장하면서 서버와의 무상태성을 구현할 수 있다.

JWT 시스템에서 발급된 토큰은 토큰에 대한 기본정보, 전달할 정보 (로그인 시스템에서는 유저 정보), 토큰이 검증됐다는 것을 증명해주는 signature를 포함한다.
사용자 인증에 필요한 모든 정보를 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요없다(self-contained).
JWT를 만들때는 JWT를 담당하는 라이브러리가 자동으로 인코딩 및 해싱 작업을 해준다.

json 토큰생성 사이트: https://jwt.io

인증과 인가

인증(Authentication)은 등록된 사용자인지 확인하는 과정이고,
인가(Authorization)는 권한이 있는 사용자인지 확인하는 과정이다.

http 특성 때문에 인증, 인가 과정은 꼭 필요하다.
http는 요청이 들어오면 응답하는 구조인데, 응답 이후 상태가 저장되지 않기 때문에(stateless), 요청을 보낸 사용자가 등록된 사용자인지와 요청한 작업 권한을 가지고 있는지를 검증해야 한다.

서버 기반 인증 vs. 토큰 기반 인증

서버 기반 인증 방식

JWT와 같은 토큰으로 사용자를 인증/인가하는 방법을 사용하기 전에는 인증에 필요한 정보를 모두 서버에 담고 있다가 클라이언트에서 요청이 왔을 때 응답하는 서버 기반 방식으로 사용자를 인증했다.

서버 기반 인증은 서버를 확장하기 어렵다는 큰 단점이 있다.
어떤 사용자가 로그인했을 때 사용자가 처음 로그인했던 그 서버, 즉 그 사용자 정보가 담긴 서버에만 요청을 보내도록 설정을 해야 사용자 정보를 불러올 수 있다.

토큰 기반 인증 방식

서버에 세션이 존재하지 않고 클라이언트 쪽에서 사용자의 로그인 상태를 관리하므로 어떤 서버로 요청이 들어가든 상관없다. 이는 곧 서버를 쉽게 확장할 수 있다는 이야기가 된다.

JWT 토큰 방식 순서

  1. 사용자가 회원가입을 하면서 서버의 DB에 사용자의 정보가 저장된다.
  2. 사용자가 로그인하면 클라이언트가 로그인한 정보(아이디, 비밀번호 등)를 서버로 보낸다.
  3. 서버에서는 받은 정보를 DB에 확인해서 인증이 되면 Access token(JWT 토큰)을 생성하여 발급한다.
  4. 클라이언트는 발급받은 토큰을 쿠키에 저장한다.
    ** 로컬 스토리지는 해커가 스크립트를 통해 탈취할 수 있기 때문에 잘 쓰지 않음
  5. 이후 서버에 요청을 보낼 때마다 서버에게서 받았던 토큰을 헤더에 담아서 함께 보낸다.
  6. 서버에서는 토큰의 유효기간과 토큰의 '서명'부분을 확인하여 사용자 정보를 확인(인가)한 뒤, 요청받은 정보를 클라이언트에게 보낸다.

이렇게 하면 모든 정보는 클라이언트 측의 토큰 내에 저장되기 때문에
서버에서는 사용자의 정보를 따로 관리할 필요가 없어진다.

=> 서버의 무상태성 구현 (서버에서 '상태'를 관리하지 않음)

JWT 토큰의 구조

토큰의 맨 뒤에 붙는 서명(signature)을 통해 특정 사용자의 정보를 식별하게 된다.

Refresh 토큰

출처: https://velog.io/@daybreak/Access-Token-Refresh-Token

refresh token은 처음에 로그인을 완료했을 때 access token보다 긴 유효기간을 가지고(예: 90일) access token과 동시에 발급된다.

access token이 만료되었을 때 refresh token이 유효하다면
유저가 새로 로그인을 하지 않아도 서버에서 새 access token을 발급한다.

Refresh 토큰은 기존 Access 토큰이 만료된 후 추가 Access 토큰을 발급받기 위한 기준으로 사용되며, access 토큰과 마찬가지로 유효기간이 지나면 만료되지만 만료되기까지의 기간은 훨씬 길다.

1) refresh token 덕분에 access token의 유효기간을 짧게 해둘 수 있어 더 안전한 통신이 가능하다.

2) refresh token마저 만료되면 사용자는 새로 로그인을 해야 하지만, 그 전까지는 로그인을 안 해도 된다.

하지만 refresh token도 해킹될 가능성은 있기 때문에 적절한 유효기간 설정이 필요하다.

profile
영어강사, 프론트엔드 개발자를 거쳐 데이터 분석가를 준비하고 있습니다 ─ 데이터분석 블로그: https://cherylog.tistory.com/

0개의 댓글