JWT 기반 인증 방식

인증 방식을 알아보자 2편

앞서 알아본 세션 기반 인증 방식에는 다음과 같은 문제점이 있었다.

  1. 서버에 과부화를 유발한다.
  2. 서버 확장이 어려워진다.
  3. CORS 방식 사용이 어렵다.

이런 문제들을 해결하고자 등장한 JWT 기반 인증 방식에 대해 알아보자.



👀 용어 정리

(1) JWT

JWT란 JSON Web Token의 약자로 속성 정보(Claim)를 JSON 데이터 구조로 표현한 토근이며, RFC7519 표준이다. 여기서 토큰은 로그인 후 서버에서 만들어 전달하는 문자열을 뜻한다. 토큰 안에는 사용자의 로그인 정보와 해당 정보가 서버에서 발급 되었음을 증명하는 서명이 들어있다.

JWT의 구조

JWT는 세 파트로 나누어지고, .을 통해 구분한다. 아래 순서대로 구성된다.

  1. Header

    토큰의 타입과 해시 암호화 알고리즘(HMAC, RSA 등..)으로 구성되어 있다.

  2. Payload

    토큰에 담을 정보를 포함하고 있다. 여기에 담는 정보의 한 조각을 Claim이라고 부르며, JSON 형식(name: value)으로 이루어져 있다. 여러 개의 Claim을 넣을 수 있다.

    Claim은 registered(등록된), public(공개), private(비공개)의 세 종류가 있다.

  3. Signature

    서버에서 발급되었음을 증명하는 서명이다. secrete key를 포함하여 암호화 되어 있고, 보통 해시 암호화 알고리즘 중 HMAC SHA256 또는 RSA SHA256을 사용한다.

    서명이 있기 때문에 무결성이 보장된다. 즉, 정보가 변경되거나 위조되지 않았음을 의미한다.

(2) Access token || Refresh token

Access token

사용자가 Request를 보낼 때 헤더에 포함시켜, 서버에 접근을 허용 받기 위해 사용하는 토큰이다. 토큰의 유지 기간을 10 ~ 15분으로 짧게 두어 자주 발급 받게 해, 다른 사람에게 도난 당하더라도 금방 만료되어 안정성을 유지할 수 있도록 했다.

Refresh token

Access token이 만료되었을 때 재발급 받기 위한 인증 수단으로 사용하는 토큰이다. 평소 Request를 보낼 때는 포함되지 않으며, Access token을 재발급 하기 위한 Request에만 사용한다. 유지 기간은 Access token에 비해 길게 정하고(보통 180일 정도 설정한다.), 만료될 경우 사용자가 다시 로그인을 해 재발급 해야 한다.



⚙️ 동작 방식

image

  1. 사용자가 로그인을 요청한다. ID, Password 정보가 유효하다면(DB에 저장된 값이라면), Secret key를 사용해서 Access token, Refresh token을 발급한다.

  2. 서버에서 Access token, Refresh token을 전달한다.

  3. 사용자는 전달 받은 토큰들을 localStorage에 저장한다.

  4. 사용자는 Request 할 때 헤더에 Access token을 함께 전달한다. (나 로그인한 사용자야!라고 서버에게 알리기 위해)

  5. 서버는 사용자가 보낸 Access token을 확인하고, 유효하다면 Response 한다.

만약 Access token이 만료되었다면?

사용자가 미리 Access token을 decode 해서 남은 기간을 확인 하는 게 좋다. 그러면 아래 그림에서 1~3번에 해당하는 과정을 거치지 않아도 돼 대기 시간이 줄어들기 때문이다.

image



👍 좋은 점

  1. 서버 부담이 없다.

    토큰(JWT)을 사용자의 localStorage에 저장하므로 서버의 메모리, DB등의 부담이 없다.

  2. 서버 확장이 용이하다.

    서버가 사용자의 상태 정보를 저장하지 않으므로 Stateless server이다. 따라서 로드 밸런싱을 사용한 서버 확장이 용이하다.

  3. 보안성이 좋다.

    • 쿠키에 SessionId를 담아 주고 받는 방식이 아니기 때문에 안전하다.

      Session 기반 인증 방식에서는 A의 게정 정보(ID, PW)를 모르더라도 SessionId만 알면 A인것처럼 서버에 요청을 보내고 서비스를 이용할 수 있는 문제가 있다.

    • Access token의 유지 기간이 짧기 때문에 타인에게 도난 당하더라도 안전한 편이다.

  4. CORS 방식을 사용하기에 용이하다.

    토큰이 유효하다면 어떤 디바이스, 도메인이든 정상적으로 처리된다.


🙏 아쉬운 점

  1. 서버에서 사용자의 상태 정보를 저장하고 있지 않기 때문에 사용자의 로그인 여부 확인이나 강제 로그아웃 같은 제재를 가하는 데에 어려움이 있다.

  2. 사용자가 임의로 토큰을 수정하거나 구조를 변경할 시, 서버에서 확인할 수 없기 때문에 Session 기반 인증 방식에 비해 상대적으로 안정성이 낮다.

  3. Refresh token이 도난됐을 경우, 악용될 가능성이 있다.

  4. 일반적으로 Payload 부분에 필요한 사용자 정보를 모두 저장하는 경우가 많아 SessionId에 비해 길이가 길다. 따라서 HTTP Request가 무거워질 수 있다.

  5. 토큰에 민감한 정보를 포함하는 경우 위험할 수 있다.



📚 참고

JWT 기반 인증 방식

Joie-Kim

Joie-Kim

배운 것을 기록하는 습관! ✍️

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin pinterest medium vimeo stackoverflow reddit quora quora