과거, 동아리 홈페이지를 만들던 시절에 커뮤니티 기능을 위해선 각 동아리 회원별로 할 수 있는 기능이 제한되므로 별도로 인증을 해야 했고, 자연스럽게 세션에 회원의 id 와 회원등급을 저장해 인증을 수행했다. 당시에 동아리 홈페이지 자체가 사용이 많지도 않았고, 거의 개인 프로젝트정도로 이런 걸 만들어봤다 정도여서 별 고민은 없었는데, REST API 에 대한 공부를 하면서 다음과 같은 의문을 가졌다.
REST API 는 stateless 이기 때문에 클라이언트의 상태정보를 저장하지 않는데, 사용자 인증을 위해 session을 사용하면 REST API 가 의미가 없는 것 아닌가?
그렇게 정보를 찾은 결과, REST API 는 세션이 아니라 토큰을 이용해 인증작업을 수행한다는 것을 알았다. 두 방식의 차이점을 알아보았다.
1. 크기 및 부하
정확히는 클라이언트와 서버에 저장되는 인증정보의 크기가 다르다. 세션방식은 서버에 세션을 저장하고, 클라이언트는 sessionID 수십 바이트 정도만 저장하는 반면, 토큰은 인증정보 자체가 토큰에 모두 저장되고, 이를 클라이언트에 저장한다. 따라서, 토큰 방식이 세션 방식에 비해 클라이언트의 부하가 크다.
또한, 상대적으로 크기가 큰 토큰을 매 요청시에 패킷에 포함시키므로, 사용자가 많은 서비스라면 네트워크에 부하가 세션 방식에 비해 좀 더 크다. 정리하면 다음과 같다.
클라이언트 크기 | 서버 크기 | 네트워크 부하 | |
세션 | 작다 | 크다 | 작다 |
토큰 | 크다 | 작다 | 크다 |
2. 안전성
세션 방식은 인증 정보가 서버에 저장되므로, 토큰 방식에 비해 세션에 저장된 정보가 안전하게 유지되기가 쉽다. 물론, 세션 아이디가 유출되면 무력화되므로, HttpOnly 옵션과 Secure 옵션을 지정해 쿠키에 저장한다.
반면 토큰 방식은 인증 정보가 모두 토큰에 저장되고, 토큰이 클라이언트에 저장되기 때문에 언제든지 탈취될 수 있다. 따라서, 민감한 정보는 절대 토큰에 저장하면 안된다. 또한, 토큰을 발급할 때 유효기간을 짧게 하여 발급하고, 인증용 토큰과 함께 인증 갱신용 토큰(refresh Token)을 함께 발행하여 짧은 인증기간으로 인한 재로그인을 막는다.
안전성 | 민감 정보 저장 가능여부 | |
세션 | (비교적)높음 | 가능하지만 권장하지 않음. |
토큰 | (비교적)낮음 | 불가능. |
3. 확장성
소규모의 서비스를 제작할 때는 세션이든 토큰이든 부하가 작기 때문에 아무거나 사용해도 되고, 서버도 한 대면 충분하다. 그러나, 서비스의 규모가 커지면 서버 한대로는 부하를 감당하기 힘들어지게 된다. 따라서, 서버를 여러 대 두고, 각 요청을 어떤 서버에 매핑할지 결정하는 로드 밸런서를 두게 된다. 세션방식의 경우 이런 구조에서 매우 불리하다. 최초 접속자의 세션을 각 서버에서 따로 생성한다면, 다음 요청이 이전 요청과 같은 서버로 온다는 보장이 없으므로, 모든 서버가 즉시 세션정보를 동기화 해야한다. 이는 추가 부하를 의미한다. 이를 해결하기 위한다고 세션을 관리하는 서버를 한대 더 둔다고 해도, 대규모 서비스의 많은 사용자가 생성한 세션을 관리하려면 부하가 심해진다. 수많은 인증정보를 서버에 저장해야하기 때문이다.
반면 토큰 방식은 인증정보를 관리할 필요가 없기 때문에 세션처럼 인증을 위한 추가 부하가 발생하지 않는다.
서버 분산 환경에 | |
세션 | 불리 |
토큰 | 유리 |
'Security' 카테고리의 다른 글
업데이트 배포서버가 해킹된다면? - 2편 (0) | 2021.01.11 |
---|---|
업데이트 배포서버가 해킹된다면? - 1편 (0) | 2021.01.05 |
CSRF 실습 (0) | 2020.09.23 |
XSS (0) | 2020.07.19 |