본문 바로가기

Web.d

[Web][Network] Session vs Token Authorization

반응형

[ 2023/10 ] 2022/01에 작성한 내용을 보충하여 재발행합니다.

 

세션과 토큰, 백엔드와 프론트엔드가 용어를 이해하는 영역이 다르다.

그 말은 즉슨, 엔지니어 간에 제대로 소통하기 위해서는 양쪽에서의 올바른 이해가 필요하다.

Authorization 과정에 대한 Session 과 Token의 차이점을 살펴보자.

 

세션 (Session)

세션으로 로그인하는 과정을 살펴보자.

 

  1. Client) user가 브라우저에서 로그인 폼을 제출한다. 이로 인해 로그인 정보로, HTTP 통신이 일어난다.
  2. Server) user 정보로, Session을 생성하여 DB에 저장한다. 
    session에 해당하는 session ID를 Response로 반환한다.
  3. Client) session ID를 Cookie에 저장한다. (FYI, 쿠키를 이용한 세션 방식으로 CSRF 공격 위험이 대두된다. 이를 프론트엔드에서 해결하기 위한 방법 중 하나로, 서버에서 사용자의 요청에 Referrer 정보를 확인하는 방법이 있다. 요청 헤더(request header) 정보에서 Referrer 정보를 확인할 수 있다. 보통이라면 호스트(host)와 Referrer 값이 일치하므로 둘을 비교한다. CSRF 공격의 대부분 Referrer 값에 대한 검증만으로 방어가 가능하다고 한다..) 🔗CSRF, Reference
  4. Client) 저장한 session ID를 통해 future Request에 담아 통신한다.
  5. Server) session ID에 대한 valid check를 진행한 후 작업을 처리한다.

 

Fig.1) 세션 통신 과정

 

Cons.

  1. 오직 session ID로 인증하고, session DB에 저장된 정보를 찾아 불러줘야 한다.
    유저의 모든 정보를 직접 저장하기 때문에, 유저가 많아질 수록 DB의 크기도 커져야 한다.
    이는 클라우드 형태로 분산된 DB를 관리할 때, 각각의 DB를 확인하고 관리해야 함을 의미하기도 한다.
  2. CSRF; Cross-site request forgery 보안에 취약한다.

 


토큰 (Token)

토큰으로 로그인을 진행하는 과정도 살펴보자

 

  1. Client) user가 브라우저에서 로그인 폼을 제출한다. 이로 인해 로그인 정보로, HTTP 통신이 일어난다.
  2. Server) Token을 발급한다; JWT(JSON Web Token)을 생성한다.
    서버의 private key를 이용하여 생성한다.
  3. Client) JWT를 브라우저 local storage에 저장한다.
    토큰을 어떻게 관리하는가에 대해서 여러 인사이트들이 있다. 아래와 같은 방식을 많이 사용하는 듯하다. 보안적으로 제대로 학습해보지는 못하였다.
    → refreshToken은 secure httpOnly 쿠키로 받아와 로컬 변수로 이용.
    → accessToken은 JSON Payload로.
  4. Client) 저장한 session ID를 통해 future Request에 담아 통신한다.
  5. Server) header에 담긴 JWT에 대한 validate를 진행한다. (Authorization: Bearer <token>)
    JWT에 정보가 담겨있기 때문에, DB가 모든 정보를 보고 있을 필요가 없다.

 

Fig.2) JWT 토큰 통신 과정

 

vs Session

  1. 브라우저에 정보를 저장하고 관리하기 때문에, 토큰 탈취(보안)에 취약하다.
  2. 세션은 server에서 유저 정보를 관리하고 인증 상태를 처리하지만
    토큰은 클라이언트에서 관리된다.
    그로 인해, 유저들의 상태를 언제든 제어할 수 있지 않다. 토큰을 탈취당해도, 무효화 할 방법이 없다.
    이를 해결하기 위해, 로그인 시 access Token, refresh Token을 별도로 제공한다.
    • accessToken: 매번 인가를 받을 때 사용하는 토큰. (보통 수명이 짧다.)
    • refreshToken: accessToken의 수명이 다했을 때 accessToken을 재발행 받기 위한 토큰이다. 보통 2주 정도 기간이 길게 처리한다. (누군가를 로그아웃시키려면 refeshToken을 db에서 지워버리면 되는데 그래도 accessToken의 수명 동안은 바로 차단할 방법은 없다.)

서비스가 커지고, 유저 관리의 니즈가 있다면, Session 형태로의 전환이 필요하다.

 

JWT?

JWT는 필요한 모든 정보를 자체적으로 지니고 있다.

유저의 정보를 signature의 유효성을 검사하여 검사가 완료된 정보를 string 형태(토큰)로 보내는 형식으로 이루어진다. 로그인할 때 주는 토큰을 Server가 기억하고 있지 않는다.

즉, Server는 DB를 건드리지 않고, 정보를 사인하고 전달하는 것이 다인 것이다. 

 

JWT 시스템에서 발급된 토큰은, 토큰에 대한 Header 정보 / 유저 정보 / 토큰이 검증된 것을 증명해주는 Signature 정보로 이루어져 있다.

그렇기 때문에 이는 두 개체 사이에서 손쉽게 전달될 수 있다. 웹서버의 경우는 HTTP의 헤더에, 혹은 URL의 파라미터로 전달할 수 있다.

JWT는 제 3자가 쉽게 볼 수 있기 때문에 그 안에 정보는 숨겨주는 것이 좋다.

 

Fig.3) JWT 구조
Fig.4) jwt.io

반응형