매 요청마다 로그인을 하지 않기 위해 인증 정보를 어딘가에 기록해야한다.
기록하는 곳에 따라 인증 방식을 나누는데 오늘날 가장 많이 사용되는 두 가지 방식이 있다.
하나는 세션이고 다른 하나는 토큰이다.
세션 인증 방식은 서버에 인증 정보를 기록한다.
반대로 토큰 인증 방식은 클라이언트에 인증 정보를 기록한다.
두 방식을 여러 측면에서 살펴보자.
우선 자원 관리 측면에서 보면,
각 사용자의 인증 정보를 서버에 저장하지 않는 토큰이 세션보다 서버 자원을 더 아낄 수 있다.
트래픽이 증가할수록 이러한 이점이 증대된다.
코드 복잡도 측면에서 보면,
세션과 달리 토큰은 사용자가 관리하기 때문에 위변조 가능성이 있다.
따라서 이를 검증하는 추가적인 로직이 필요하다.
또 로그아웃과 같은 상황에서 세션은 만료 로직이 간단하지만,
토큰은 블랙리스트와 같은 추가적인 로직 구현이 필요하다.
오늘날 대용량 트래픽을 처리하기 위해 서버를 다중화하는데,
서버에 상태를 기록하기 위해서 공용 저장소가 필요하다.
(저장소를 따로 관리하면 동기화 문제를 해결하는데 많은 노력이 필요하다)
토큰은 서버에 상태를 기록하지 않기 때문에 추가적인 공용 저장소가 필요하지 않다.
여기까지 정리해보면 토큰 방식이 세션 방식에 비해 더 유용해 보인다.
하지만 토큰 방식에는 큰 단점이 존재한다.
앞에서 살짝 언급했지만, 토큰은 서버에 상태를 남기지 않는다.
따라서 서버는 토큰에 대한 관리가 불가능하다.
만약 토큰이 탈취 당했을 경우 토큰이 만료되기 전까지 토큰을 계속 사용할 수 있다.
이를 대처하기 위해 토큰의 만료 시간을 줄이고 블랙리스트를 도입한다.
결국 토큰 방식도 서버에 상태를 남기게 되고, 세션에 비해 토큰이 가지는 이점이 줄어든다.
게다가 토큰의 만료 시간이 짧아져 더 자주 로그인을 요구하게 되고 사용자 경험을 저하시킨다.
리프레시 토큰은 만료 시간이 짧은 액세스 토큰의 단점을 보완한다.
또 액세스 토큰을 갱신할 때 블랙리스트 확인이 이루어지므로 공용 저장소의 부하를 줄일 수 있다.
단순히 세션과 토큰을 놓고 봤을 때 토큰이 세션에 비해 확장에 용이하다.
하지만 토큰은 보안적 측면에서 관리가 불가능하다는 단점이 있고,
이러한 토큰의 단점을 보완하기 위해 블랙리스트, 리프레시 토큰과 같은 방식이 같이 사용된다.
따라서 토큰 방식도 서버에 상태를 기록한다.
토큰은 여러 방식이 함께 사용되기 때문에 세션에 비해 구현이 복잡하다.
하지만 모든 사용자에 대한 정보를 기록하는 세션에 비해
블랙리스트만 기록하여 서버 자원을 비교적 적게 사용한다.
또 매 요청마다 공용 저장소를 사용하는 세션에 비해 액세스 토큰 갱신 때만 사용하여
공용 저장소에 부하를 비교적 적게 준다.
결국 토큰의 장점인 무상태성을 일부 희생하여 보안적 측면에서 관리의 단점을 보완한다.
또 비교적 자원을 효율적으로 사용하고 약간의 성능 향상을 얻는다.
프로젝트 특성을 고려해서 적절한 기술 선택이 필요하다.
프로젝트 규모가 크지 않고 예상되는 트래픽이 적다면 세션 방식이 유리할 수 있다.
| 구 분 | 세 션 | 토 큰 |
|---|---|---|
| 서버에 상태 기록 | O | O |
| 구현 복잡도 | 간 단 | 복 잡 |
| 자원 효율성 | 낮 음 | 높 음 |
| 공용 저장소 부하 | 높 음 | 낮 음 |
| 적합한 트래픽 | 낮을 때 | 높을 때 |
보통 인증 관리를 위한 공용 저장소는 빠른 응답을 위해 인메모리 디비를 많이 사용한다.
따라서 저장하는 데이터를 최적화할 필요가 있다.
기본적으로 세션 데이터에는 부수적인 데이터가 많기 때문에 최적화하는데 많은 노력이 필요하다.
트래픽 감당을 위해 Scale-Up보다 Scale-Out이 선호된다.