세션 vs 토큰

김명일·2022년 6월 27일
0

HTTP통신은 stateless한 방식으로 첫 요청과 두번째 요청에 있어서 연관이 없다. 따라서 해당하는 인증된 사용자인지 아닌지에 대해 알 수 없다. 이러한 점을 극복하기 위해 세션과 토큰을 사용할 수 있다.


세션 기반 인증

세션은 사용자 인증(로그인) 후 사용자의 정보를 서버에 저장해 놓은 것을 의미한다.

  1. 로그인한다.
  2. 사용자 정보와 만료시기를 포함한 세션을 서버에 생성한다.
  3. 해당 세션의 아이디를 쿠키에 담아 반환한다.
  4. 클라이언트에서는 요청시 마다 자동으로 쿠키에 있는 세션아이디를 전송하기 때문에, 해당 세션아이디를 통해 인증된 사용자인지 확인한다.

이 때, 세션을 저장하는 위치는 메모리일 수 있고, 데이터베이스일 수도 있다. 하지만 대부분의 서버는 한개의 인스턴스만 가지고 있지 않기 때문에 데이터베이스에 저장하는 방식이 일반적인 것 같다.

데이터베이스에 저장하지 않는다면, 로드밸런서에서 첫 인증한 서버 인스턴스로 해당 사용자를 계속해서 보내야 한다. WHY? 해당 서버인스턴스에 세션 정보가 있기 때문이다. 하지만 데이터베이스에 저장하게 되면 어떤 인스턴스로 요청을 보내던 데이터베이스에서 조회하기 때문에 문제가 되지 않는다.


토큰 기반 인증(JWT)

사용자 인증시 토큰을 발행해 해당 토큰을 통해 사용자를 인증하는 방식이다.

  1. 로그인한다.
  2. 사용자 정보를 포함한 토큰(엑세스토큰)을 반환한다.
  3. 요청시 해당 토큰을 헤더에 추가하여 함께 요청을 보낸다.
  4. 토큰을 해독하여 인증된 사용자의 정보를 확인한다.

차이점

  1. 세션은 별도로 세션을 저장하지만 토큰은 저장하지 않는다.
    1-1. 별로도 세션을 저장하기 때문에, 해당 세션을 제거함으로서 부적절한 접근 확인시 즉각적으로 대처 가능하다.
    1-2. 다중기기를 지원하지 않은 경우, 다른 기기에서 사용한 세션을 제거하여 로그아웃 시킬 수 있다.
    1-3. 세션을 보통 데이터베이스에 저장하기 때문에 많은 데이터용량이 필요하다. 토큰 기반 인증시 토큰 데이터를 저장하지 않아도 되므로 좋다.

  2. 토큰은 별도로 저장하지 않기 때문에, 토큰 탈취시 대처가 힘들다.
    2-1. 방법1. 만료 시기를 짧게 설정한다. 하지만 자주 로그인해야하는 단점이 있다.
    2-2. 방법2. 블로그 글을 작성시작하거나 주문을 시작할 때 등 적절한 상황에 토큰을 갱신하여(sliding session) 사용한다. 하지만 역시 지속적인 사용이 아닌 짧게 짧게 사용할 경우, 사용자가 다시 로그인 해주어야 한다.
    2-3. 방법3. refresh token을 사용한다. 짧은 주기의 엑세스 토큰과 긴 주기의 리프레시 토큰 2가지를 발행하여, 요청에는 엑세스 토큰을 사용하고, 엑세스 토큰이 만료된 경우, 리프레시 토큰을 통해 토큰을 재발행하는 방법이다. 엑세스 토큰 주기를 짧게 설정할수록 탈취되더라도 빠르게 만료되기 때문에 비교적 안전하다. 하지만 자주 토큰을 갱신하는 요청이 필요하다는 단점이 있다. 적절히 시간을 선택하는 것이 좋다.
    2-4. 방법4. sliding session과 리프레시 토큰을 같이 사용한다. sliding session과 리프레시 토큰의 장점을 모두 가져갈 수 있다.
    2-5. 리프레시 토큰이 탈취당한다면? 또 하나의 리프레시토큰을 여러번 사용한다면? 비정상적인 사용자를 로그아웃 시켜야 한다면? 과 같은 문제들을 해결하기 위해 데이터베이스에 리프레시 토큰을 저장하게 된다. 즉, 저장이 필요없는 토큰의 장점이 사라지게 된다.

  3. 세션과 모바일 환경
    3-1. 일반적으로 세션저장시 IP, 로그인 시기, 사용자 정보 등을 저장한다.
    3-2. 모바일은 자주 IP가 변경되기 때문에 다른 세션으로 취급하여 인증을 필요로 한다.
    3-3. 자주 로그인해야하는 문제가 발생할 수 있다. 물론 IP를 비교하지 않을 수도 있다.
    3-4. 일반적으로 앱에서는 토큰 인증 방식을 사용하는 것 같다.


결과

결과적으로 적절한 상황에 필요한 인증방식을 선택해야 하는것 같다. 보안적인 이슈가 발생했을 때, 즉각적인 처리가 필요하다면 세션, 가볍고 중요한 정보를 다루지 않는 경우엔 토큰을 사용하는 것이 좋아보인다.

profile
주니어 백엔드 🐶🦶🏻📏

0개의 댓글