Skip to content
On this page

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

수정하기
문서 생성 2022-09-11 20:37:01 최근 수정 2023-01-16 22:31:07

인증 (Authentication)

사용자가 자신이 누구인지 주장하는 것에 대해서 참인지 거짓인지 확인하는 것

  • ex) 로그인

인가 (Authorization)

어떤 사용자가 특정 리소스에 접근하려고 할 때 권한이 있는지 없는지 검사해서 허가해주는 절차

HTTP의 특성(비연결성, 무상태)

HTTPstateless한 특징이 있다. 그래서 각 통신의 상태가 저장되지 않는다. 바로 직전의 통신도 기억하지 못하는 것이다. 그렇다면 매번 페이지를 새로 요청할 때마다 새로 로그인을 해야 하는 것일까? 어떻게 하면 이미 인증과정을 거친 사용자인지 확인할 수 있을까?

이 문제를 해결하기 위해 세션(session)토큰(token)이 등장했다.

🍪 쿠키

세션과 토큰을 알아보기 전에 세션(또는 쿠키를 사용하는 토큰)에서 사용하는 쿠키에 대해 알아보자.

쿠키는 웹 브라우저에 저장되어있는 키-값 형식의 데이터다. 크롬의 경우 개발자 도구에서 현재 저장된 쿠키를 확인할 수 있다.

F12 > Application > Cookie

쿠키는 웹 서버가 응답을 보낼 때 Set-Cookie 헤더를 통해 생성된다. Cookie 헤더를 받은 웹 브라우저는 저장장치에 쿠키 데이터를 생성해 저장한다.

이후에 웹 브라우저가 요청을 보낼 때 웹 서버의 도메인에 해당하는 모든 쿠키값이 Cookie 헤더를 통해 함께 전달된다. 이를 통해 서버는 요청을 보낸 클라이언트의 고유한 상태를 구분할 수 있게 된다.

HTTP Response의 Set-Cookie 헤더를 주는 방법 외에도 웹 브라우저에서 JavaScript로 쿠키를 제어할 수도 있다. → document.cookie

세션 기반 인증

쿠키를 이용해 인증하는 방식을 생각해보자.

요청이 들어올 때마다 쿠키를 통해 클라이언트를 구분해서 그 상태를 확인할 수 있다. 예를 들어, Cookie: name=padosum을 가진 Request와 Cookie: name=yj를 가진 Request가 있다면 각각 그에 따른 Response를 줄 수 있다.

로그인의 경우를 생각해볼까? 사용자 아이디와 비밀번호를 받고, 올바른 경우 Set-Cookie: name=padosum과 같이 쿠키를 생성해주고, 이후에는 name이라는 쿠키를 확인해서 클라이언트 구분을 할 수 있다. ☠️ 하지만 쿠키는 쉽게 조작이 가능하기 때문에 인증을 이런 방식으로 구현해서는 위험하다!

세션이란 개념이 도입되었다. 사용자의 인증 정보가 서버의 세션 저장소에 저장되는 방식이다.

사용자 로그인 구현 시 세션 기반 인증 방식을 살펴보자.

  1. 사용자 아이디, 비밀번호로 로그인 요청을 한다.
  2. 서버에서 해당 계정 정보를 검증하고 정확하다면 해당 인증 정보를 서버의 세션 저장소에 저장
  3. 사용자에게 저장된 세션 정보의 식별자인 session id를 발급
  4. 발급된 session id는 브라우저의 쿠키 형태로 저장 → 실제 인증 정보는 서버에 저장
  5. 브라우저는 인증 절차를 마친 이후의 모든 요청마다 HTTP Cookie 헤더에 session id를 함께 서버로 전송한다.
  6. 서버는 요청을 전달받고 session id에 해당하는 세션 정보가 세션 저장소에 존재한다면 해당 사용자를 인증된 사용자로 판단

세션을 이용하면 민감한 데이터를 클라이언트에게 노출하지 않고 클라이언트의 상태를 제어할 수 있다.

토큰 기반 인증

세션이 인증 정보를 서버에 저장하는 방식이라면, 토큰 기반 인증은 인증 정보를 클라이언트가 직접 들고 있는 방식이다.

인증 정보는 토큰의 형태로 브라우저의 localStorage(혹은 쿠키)에 저장된다.

  • 토큰의 종류에 따라 다르지만, 대표적인 토큰인 JWT(JSON Web Token)의 경우 디지털 서명이 존재해서 토큰의 내용이 위변조 되었는지 서버 측에서 확인 가능

사용자 로그인 구현 시 토큰 기반 인증을 살펴보자. 시스템마다 크고 작은 차이가 있지만 대략 다음과 같다고 한다.

  1. 사용자 아이디, 비밀번호로 로그인 요청을 한다.
  2. 서버 측에서 해당 계정 정보를 검증한다.
  3. 계정 정보가 정확하다면 서버 측 유저에게 인증이 되었다는 토큰을 발급해준다.
  4. 클라이언트는 전달받은 토큰을 저장해둔다.
  5. 이후 서버 요청마다 사용자가 가지고 있는 토큰을 HTTP의 Authorization 헤더에 실어 보낸다.
  6. 이 헤더를 수신한 서버는 토큰이 위변조되었거나 만료 시각이 지나지 않았는지 확인한 이후 토큰에 담겨있는 사용자 인증 정보를 확인해 사용자를 인가한다.

세션 기반 인증과 토큰 기반 인증 비교

사이즈

  • 세션의 경우 Cookie 헤더에 session id만 실어 보내면 되므로 트래픽을 적게 사용한다.
  • JWT(JSON Web Token)의 경우 사용자 인증 정보와 토큰의 발급 시각, 만료 시각, 토큰 id 등 세션에 비해 크다. 그래서 더 많은 트래픽을 사용한다.

안전성과 보안

  • 세션의 경우 모든 인증 정보가 서버에서 관리되기 때문에 보안 측면에서 조금 더 유리하다.
    • 예를 들어 보안팀이 어떤 계정이 손상된 것으로 의심되는 경우 세션 ID를 비활성화해 사용자가 로그아웃되도록 할 수 있다.

확장성

  • 일반적으로 현대 웹 애플리케이션은 한 대가 아닌 여러 대의 서버가 요청을 처리한다. 그래서 별도 작업을 처리해주지 않으면 세션 기반 인증은 세션 불일치 문제를 겪게 된다.
    • 또한 서버에서 세션 데이터를 저장, 관리하기 때문에 세션 관련 데이터양이 많아질 경우 서버에 부담이 증가할 것이다.
  • 하지만 토큰 기반 인증은 클라이언트에 토큰이 저장되기 때문에 세션 불일치 문제가 발생하지 않는다.
    • 클라이언트에 데이터를 저장하기 때문에 서버의 메모리에 부담이 되지 않는다.

결론

각각의 장/단점이 존재하기 때문에 개발자가 애플리케이션 요구사항에 더 적합한 방법으로 결정해야 한다!

참고 자료

같이 보기

Tags