토큰기반 인증방식과 JWT

younk·2023년 10월 15일
0

HTTP의 비상태성(Stateless)

HTTP는 비상태성이라는 특성을 가진다. 서버는 클라이언트의 상태를 저장하지 않으며, 따라서 이전 요청과 다음요청의 맥락이 이어지지 않는다. HTTP는 이전에 발생한 통신을 기억하지 못하기 때문에, 이전에 클라이언트가 인증과정을 거쳤는지 알 수 없다. 하지만 매번 화면을 조회할 때마다 사용자에게 인증을 요구할 수는 없기 때문에, 세션과 토큰을 이용하여 인가(Authorization)를 수행한다.

세션기반 인증


세션기반 인증은 사용자의 인증정보가 서버의 세션 저장소에 저장되는 방식이다. 사용자가 로그인을 하면 해당 인증정보를 서버의 세션 저장소에 저장하고, 세션 id를 부여한다. 이 세션 id는 브라우저에 쿠키형태로 저장된다. 이후 브라우저는 HTTP 요청마다 쿠키 헤더에 세션 id를 함께 서버로 전송한다. 서버는 요청을 받으면 세션 id에 해당하는 정보가 세션 저장소에 존재한다면, 해당 사용자를 인증된 사용자로 판단한다.

토큰기반 인증


토큰기반 인증은 인증정보를 클라이언트가 직접 들고 있다. 이때 인증정보는 토큰의 형태로 브라우저의 로컬스토리지 혹은 쿠키에 저장된다. JWT의 경우, 디지털 서명이 존재해 토큰의 내용이 위변조 되었는지 서버측에서 확인 가능하다.
토큰기반 인증에서는 사용자가 가지고 있는 토큰을 HTTP의 Authorization 헤더에 담아 보낸다. 그럼 서버는 토큰의 위변조 유무와 만료시각을 체크한 후, 토큰에 담겨있는 사용자 인증정보를 확인한다.

세션기반 인증 VS 토큰기반 인증

1) 트래픽 효율
세션의 경우 쿠키 헤더에 세션 id만 실어 보내면 되기 때문에 트래픽을 적게 사용한다.
하지만 JWT는 사용자 인증 정보와 토큰의 발급시각, 만료시각, 토큰의 id 등 많은 정보를 전달하므로 더 많은 네트워크 트래픽을 사용한다.

2) 안정성과 보안문제
세션은 모든 인증정보를 서버에서 관리하기 때문에, 좀더 보안에 유리하다. 만약 세션 id가 해커에 의해 탈취된다 하더라도, 서버측에서 해당 세션을 무효처리하면 된다.
반면 토큰의 경우, 클라이언트가 모든 인증정보를 가지고 있기 때문에, 한번 해커에게 탈취되면 해당 토큰이 만료되기 전까지는 속수무책으로 피해를 입을 수 밖에 없다.

3) 확장성
그럼에도 불구하고 최근 웹 애플리케이션이 토큰 기반인증을 사용하는 것은 확장성 때문이다.
일반적으로 웹 애플리케이션의 서버 확장 방식은 수평 확장을 사용한다. 즉, 한 대가 아닌 여러 대의 서버가 요청을 처리한다. 이때 별도의 작업을 해주지 않는다면, 세션기반 인증방식은 세션 불일치 문제를 겪게된다. 이를 해결하기 위해 Sticky Session, Session Clustering, 세션 스토리지 외부분리 등의 작업을 해주어야 한다.
하지만 토큰기반 인증일 경우, 서버가 직접 인증방식을 저장하지 않기 때문에 세션 불일치 문제로부터 자유롭다. 그렇기에 토큰기반 인증은 HTTP의 비상태성을 그대로 활용할 수 있고, 따라서 높은 확장성을 가질 수 있다.

4) 서버의 부담
세션기반 인증은 서비스가 세션 데이터를 직접 저장하고 관리하기 때문에, 데이터 양이 많아지면 많아질수록 서버의 부담이 증가한다.
반면 토큰기반 인증은 클라이언트가 데이터를 가지고 있기 때문에, 유저 수가 증가해도 서버의 부담이 증가하지 않는다.

JWT(Json Web Token)


jwt는 json 객체를 사용하여 정보를 전달하는 웹 토큰이다.
jwt는 토큰 자체를 정보로 사용하는 self-contained 방식으로 정보를 안전하게 전달한다.

  • self-contained(자가수용적)이란
    : jwt는 필요한 모든 정보를 자체적으로 가지고 있다. jwt 시스템에서 발급된 토큰에 대한 기본 정보, 전달할 정보, 토큰이 검증됨을 증명하는 서명을 포함한다.

jwt는 헤더, 내용, 서명이 '.'을 기준으로 나누어져있으며, 완성된 토큰은 다음과 같은 형태를 가진다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

JWT 구조


jwt의 헤더, 페이로드, 시그니처는 json 형태로 구성되며, 각 부분은 Base64로 인코딩되어 있다.

1) Header
알고리즘과 토큰 타입을 저장한다.

{
	"alg" : "HS256",
    "typ" : "JWT"
}
  • typ : 토큰의 타입을 지정 ex) JWT

  • alg : 알고리즘 방식을 지정하며, 서명(Signature) 및 토큰 검증에 사용 ex) HS256(SHA256) 또는 RSA

2) Payload
토큰에서 사용할 정보들인 클레임(claim)이 저장된다.

{
	"sub" : "1234567",
    "name" : "yunkyeong",
    "iat" : 1234567
}

클레임은 총 3가지로 나뉜다.

  • Register Claim
    이미 등록된 클레임.
    등록된 클레임은 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들이다.

    iss(issuer; 발행자),
    exp(expireation time; 만료 시간),
    sub(subject; 제목),
    iat(issued At; 발행 시간),
    jti(JWI ID)

  • Public Claims
    사용자가 정의할 수 있는 클레임. 공개용 정보 전달을 위해 사용.

  • Private Claims
    해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 외부에 공개되도 상관없지만 해당 유저를 특정할 수 있는 정보들을 담는다

3) Signature
시그니처는 (헤더 + 페이로드)와 서버가 갖고 있는 유일한 key 값을 합친 후, 암호화를 한다.이때 사용하는 암호화 알고리즘은 헤더에서 정의한 알고리즘 방식(alg)을 활용한다.
Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용된다.

Acess Token과 Refresh Token

JWT도 제 3자에게 토큰 탈취의 위험성이 있기 때문에, 현업에서는 그대로 사용하는것이 아닌 Access Token, Refresh Token 으로 나누어 인증을 하는 방식을 취한다.

Access Token 과 Refresh Token은 둘다 똑같은 JWT이다. 다만 토큰이 어디에 저장되고 관리되느냐에 따른 사용 차이일 뿐이다.

  • Access Token
    클라이언트가 갖고있는 실제로 유저의 정보가 담긴 토큰으로, 클라이언트에서 요청이 오면 서버에서 해당 토큰에 있는 정보를 활용하여 사용자 정보에 맞게 응답을 진행

  • Refresh Token
    새로운 Access Token을 발급해주기 위해 사용하는 토큰으로 짧은 수명을 가지는 Access Token에게 새로운 토큰을 발급해주기 위해 사용. 해당 토큰은 보통 데이터베이스에 유저 정보와 같이 기록.

*정리하자면, Access Token은 접근에 관여하는 토큰, Refresh Token은 재발급에 관여하는 토큰의 역할로 사용되는 JWT 이라고 말할 수 있다.
만약 Access Token 만을 이용하여 인증하면, Access Token은 발급된 이후 서버에 저장되지 않고 클라이언트에 저장되어 토큰 자체로 검증을 하며 사용자 권한 인증을 진행하기 때문에, Access Token이 탈취되면 토큰이 만료되기 전 까지, 토큰을 획득한 사람은 누구나 권한 접근이 가능해지는 문제점이 있었다.
그래서 토큰의 유효 시간을 부여하여 탈취 문제에 대해 대응을 하기도 하지만, 만일 유효 기간이 짧을 경우 그만큼 사용자는 로그인을 자주해야 하는 번거로움이 있다.
따라서 이러한 문제를 해결하기 위해 Refresh Token 이라는 추가적인 토큰을 활용하여 토큰을 이중 장막을 쳐서 보다 보안을 강화하는 식으로 보면 된다.

참고
세션 기반 인증과 토큰 기반 인증 (feat. 인증과 인가)
JWT 토큰 인증 이란? (쿠키 vs 세션 vs 토큰)

0개의 댓글