토큰(Token)

Rosevillage·2023년 3월 8일
0

토큰

쿠키 세션에 이어 또 다른 인증방식인 토큰은 최근 앱 애플리케이션에서 많이 사용되는 인증 방식 중 하나다.

우리는 이전에 세션을 통해 사용자 정보를 서버에 저장했지만, 서버 확장이 어렵고, 가용 가능한 서버의 용량이 줄어든다는 문제점을 알게 되었다. 이를 해소하기 위해서 토큰이 등장했다.

http를 배웠다면 무상태성이 서버 확장에 유리 하다는 것을 알고 있을 것이다. 토큰 인증 방식은 다음과 같은 특징을 통해 서버의 무상태성을 확보한다.

  • 토큰은 인증과 권한 정보를 담고 있는 암호화된 문자열 의미한다.
  • 토큰 인증 방식은 사용자의 정보를 암호화해 브라우저에 저장한다.
  • 서버는 사용자가 보낸 토큰이 유효한지만 확인한다.

동작 방식

토근 인증 방식은 기본적으로 쿠키 방식와 비슷하다.

다만 차이점이 있다면, 토큰은 데이터를 암호화 하고, 서버는 토큰의 유효성을 검사 한다는 것이다.

  • 클라이언트의 로그인 요청이 성공하면 서버는 사용자의 정보와 서버의 비밀 키를 담은 토큰을 생성해 쿠키나 http의 Authorization 헤더에 담아서 클라이언트에 전달한다.
  • 이후 다른 요청에서 클라이언트는 토큰을 같이 보내게 되고, 서버는 토큰의 비밀키를 통해 해당 토큰이 유효한지 검사한다.
  • 토큰이 유효하다면 요청에 따른 응답을 클라이언트에게 전송한다.

이렇게 서버가 인증을 위해 지녀야 할 정보가 없기 때문에 서버의 부담이 줄어든다.

장점

위의 설명들을 통해 다음과 같은 장점이 있음을 알 수 있다.

  • 무상태성 : 토큰에 저장된 정보와 키만으로 토큰의 유효성을 검사하기 때문에, 인증을 위한 추가적인 구조가 필요하지 않다.
  • 확장성 : 무상태성을 기반으로 하기 때문에 서버가 여려개로 늘어나도 부담이 없다.
  • 범용성 : 토큰을 여러 서버에서 받아도 문제가 없기에 인증 전용서버를 잘 구축 해놓을 경우 여러 서비스가 하나의 공통 인증을 통해 작동될 수 있다.
  • 용이한 권한 부여 : 토큰에 다양한 정보를 저장할 수 있기 때문에, 권한 부여에 용이하다.

토큰의 구성

토큰 방식을 사용할 때 사용할 수 있는 것 중 하나로 JWT(JSON Web Token)가 있다.
JWT는 데이터를 JSON 객체에 담고 토큰으로 만드는게 특징이다.

JWT는 .을 기준으로 header, payload, signature로 구성된다.

  • header : 설정 값이 위치
    토큰의 종류와 signature를 만드는 알고리즘으로 구성된객체를 base64 방식으로 인코딩해 생성한다.
    //인코딩 전
    {
      "alg":"HS256",
      "typ":"JWT"
    }
  • payload : 전달하려는 정보가 위치
    사용자 정보, 권한, 발급 일시, 유효기간 등으로 구성된 객체를 base64 방식으로 인코딩해 생성한다.
    //인코딩 전
    {
      "sub": "someInformation",
      "name": "john",
      "iat": 127622301
    }
  • signature : 비밀키와 header의 알고리즘을 통해 토큰을 해싱한다.
    비밀키가 달라지면 sigature가 달라지기 때문에 이를 통해 토큰의 무결성을 확인 할 수 있다.
    HMAC SHA256 라는 알고리즘이 있다고 하고, 그 알고리즘을 header에 할당 했다면 signature는 다음과 같은 모습을 한다.
    //인코딩 전
    HMACSHA256(base64incoding(header)+'.'+base64incoding(payload), secret)

여기서 말하는 해싱이란 간단하게 말해서 해시 함수를 통해 기존 문자열을 더 짧은 길이의 값으로 변환하는 것을 의미한다.

  • 함수를 이용해 특정 값을 반환하는 것이기 때문에 같은 입력값에는 같은 같이 반한된다.
  • 이 값들은 서버에서 레인보우 테이블이라는 원본값-반환값 쌍의 테이블에 보관하고
  • salt라는 임의의 값을 해싱 과정에 추가해 복호화가 불가능할 정도로 변환할 수 있다.

물론 만능은 아니기에 취약한 부분도 존재하나 자세한 설명은 다른 포스트에서 다루도록 하겠다.

다시 토큰으로 돌아와서,
토큰은 입장권과 비슷한 역할을 하기에 누군가 특정 사용자의 토큰을 탈취해 요청을 보낼경우, 서버는 토큰이 유효한지만 확인하고, 요청에 해당하는 응답을 보낸다.

이런 특성 때문에 서버는 토큰이 탈취 당해도 토큰을 만료시키는 등의 조치를 취할 수 없고, 유효기간이 만료되기를 기다려야 한다.

이를 보안하기 위해서 Access Token과 Refresh Token이 등장했지만, 모든 문제를 해결해 주진 못했다. 그래도 등장 했으니 간략히 설명하자면

  • Access Token : 서버에 접속하기 위해 사용되는 토큰으로 비교적 짧은 유효기간을 사용해 탈취 피해를 줄이는 역할을 한다.
  • Refresh Token : Access Token을 발급하기 위한 토큰으로 비교적 긴 유효기간을 사용해 Access Token만료되면 새로 발급하게 한다.

그렇다 Refresh Token이 탈취되면 말짱 도루묵이다.

물론 재발급 횟수를 1회로 하거나, Refresh Token을 서버에 저장하는 등의 방법이 있지만,
결국 탈취 안당하는 것이 제일 좋기 때문에, 최선의 방법은 아니다.

보는 사람이 있을까 싶지만 JWT의 취약점(결국은 토큰의 취약성과 마찬가지라 다)이 궁금하다면에 코딩애플의 영상도 한번쯤 봤으면 한다. JWT의 취약점에 대한 부분을 쉽고 재미있게 알려주고, 댓글창에 여러 의견이 있는데 나의 경우는 새롭게 알아가는 내용들이 있었다.(물론 읽어도 잘 모르기에 공부해볼 목록에 추가만 했다)

0개의 댓글