# 2022-07-07 세션 & 쿠키 방식 vs 토큰 방식
# 아고라
아고라
고대 그리스의 도시국가(폴리스)에서 자유 시민들이 자유롭게 토론을 벌이던 장소. 아고라라는 단어 자체의 의미는 '집결지'(Gathering Place)이다.
우리는 다양한 미션을 진행하며 많은 의문과 고민에 직면하게 된다. 미션을 진행하며 단순히 정답을 찾는 것이 아닌 자신만의 근거와 사례를 만들어가는 과정이라고 생각한다. 우리 아고라 에서는 구체적인 예시를 기반으로 다양한 상황을 제시한다. 참여자는 그에 대한 실제 적용 사례를 이야기 하거나 자신만의 근거를 이야기 하며 건전한 토론을 진행한다.
# 목적
미션을 진행하며 직면하는 다양한 의문들에 대한 자신만의 근거를 만들기 위한 의식적인 연습
과 자신의 생각을 의도에 맞게 적절히 전달할 수 있는 말하기 연습
이 가장 큰 목적이다.
# 세션 & 쿠키 방식 vs 토큰 방식
WARNING
해당 내용은 토론을 진행할 때 주최자가 기록한 것을 기반으로 각색한 것입니다! 모든 내용을 기록하지 못했기 때문에 잘못된 부분이나 틀린 부분이 존재할 수 있습니다. 만약 잘못된 부분이나 추가하고 싶은 내용이 있다면 아래 코멘트에 남겨주세요!
보통 신뢰할 수 있는 유저인지 확인하기 위해 인증과 인가의 절차를 거친다. 이러한 인증 로직을 구현하기 위해 대표적으로 사용하고 있는 방식은 세션 & 쿠키 방식
과 토큰 방식
이다. 우테코에서 이제 본격적인 팀 프로젝트가 시작되었다. 다양한 주제와 서비스들이 나왔고 대부분은 인증 로직을 필요로 하고 있다. 이번 아고라를 통해 어떠한 방식을 선택했고 그에 대한 의견은 무엇인지 이야기를 나눠보려 한다.
인증 방식을 선택한 팀들이 있나?
있다.
세션 & 쿠키 방식과 토큰 방식 중 어떠한 것을 선택했는가?
토큰 방식을 선택했다.
세션 & 쿠키 방식을 고려 했는가?
고려하였지만 서버 측의 부하를 줄이고, 쿠키를 지원하지 않는 모바일 앱에서 활용할 것을 대비하며 확장성을 고려하기 위해 토큰 방식을 선택했다.
세션이 서버의 부하가 크다고 언급했다. 어떤 점에서 크다고 생각하는가?
쿠케 자체에 넣는 것은 세션 id인데 그것을 활용하여 세션에 담긴 유저 정보를 조회해야 한다. 즉 서버 측에서 추가적인 절차가 늘어나기 때문에 부하가 있다고 판단했다.
JWT도 동일하게 검증된 토큰 정보를 기반으로 유저 정보를 조회한다. 동일하게 부하가 일어나는 것이 아닌가?
쿠키는 설정되면 매번 요청 헤더에 담겨 전달된다. 서버 측에서는 반복적인 절차를 통해 진행해야 한다. 하지만 JWT의 경우 필요에 따라 토큰 검증을 진행하면 되기 때문에 상대적으로 적다고 생각한다.
JWT를 사용할 때 암호화를 진행할 경우 CPU는 반복 작업을 진행한다. 특히 암호화할 때 많은 CPU 작업을 요하게 된다. 오히려 JWT가 세션 & 토큰 보다 서버에 많은 부하를 줄 수 있다는 것을 고려해야 한다.
세션 & 쿠키를 고려하지 않은 팀도 존재한다. 이유가 있을까?
보안적인 측면이 강하다. 토큰의 베스트 케이스를 이야기 하면 쿠키에 리프레쉬 토큰을 넣고 로컬 스토리지에는 엑세스 토큰을 넣는다. 이것은 csrf
등 다양한 공격에 대응할 수 있다. 자세한 내용은 추가적인 학습을 진행하려 한다.
csrf
Cross Site Request Forgery
의 준말로 웹 애플리케이션 취약점 중 하나로 인터넷 사용자가 자신의 의지와 무관하게 공격자가 의도한 행위를 특정 웹 사이트에 요청하게 만드는 공격이다.
엑세스 토큰과 리프레시 토큰은 무엇이 다른가?
엑세스는 시간이 만료되면 로그인이 만료된다. 이때 리프레시 토큰을 활용하여 액세스 토큰을 발급 받고 로그인을 유지하기 위해 사용된다.
나누는 이유는 뭘까?
엑세스 토큰의 단점을 보완하기 위해서 이다.
언급한 단점이 무엇인가?
비교적 만료 시간이 짧은 것이 문제이며 단점이다.
만료 기간을 늘리는 것으로 해결할 순 없는가?
토큰에 민감한 정보로 인해 주기를 짧게 가져가기 위함이다.
만료가 되도 페이로드에 대한 조회는 가능하다.
세션 & 쿠키는 서버 측에서 잘못된 사용자를 판단하여 만료 시킬 수 있다. 하지만 토큰은 서버 측에서 제어가 불가능하지 않은가?
그렇기 때문에 토큰에 대한 만료 시간을 적절히 조정해야 한다.
그렇다면 어느 정도의 주기가 적당하다고 생각하는가?
익명의 팀1
: 15분 ~ 30분이 적당하다고 생각한다.익명의 팀2
: 1시간으로 잡았다.- 리프레시 토큰은 추후 고려할 예정이다.
주기가 짧으면 계속해서 로그인해야 하는 번거로움이 생기지 않을까?
그 정도의 텀은 사용자가 감당(?) 해야 한다.
만약 토큰이 필요한 주문 하는 상황에서 토큰이 만료되는 경우 어떻게 해야 할까?
주문을 시작할 때 토큰을 새로 발급하는 방식으로 대처가 가능하다.
세션 & 쿠키를 사용할 때 해당 정보가 탈취 되었다는 것을 서버 측은 어떻게 인지하는가?
반복적인 요청이나 정상적이지 않은 위치에서 보낸 요청, 즉 의심스러운 요청에 대해 탈취 당했다는 것을 인지한 뒤 세션을 삭제한다.
또한 서버 측의 구현에 따라 이상한 요 청을 확인 할 수도 있게 된다.
해당 요청이 누구의 세션인지 어떻게 확인하는가?
결국 그러한 문제가 발생하면 세션 스토리지를 모두 삭제해야 한다. 이것은 세션 & 쿠키 방식의 단점이 될 수 있다.
우리는 세션 & 쿠키를 고려하기 보다 우선적으로 토큰에 대해 고려한다. API 서버를 구축한다고 가정한 뒤 인증 로직에 대한 구글링을 진행하면 토큰 방식에 대한 예제들이 주를 이룬다. 왜 토큰 방식이 먼저 고려가 되는 것인가?
토큰은 서버 측에서 DB를 가지지 않기 때문에 더 낫다고 판단한다.
세션 & 쿠키 방식도 일반적인 RDBMS가 아닌 레디스를 활용하여 보다 더 빠른 반응속도를 만들어 낼 수 있다.
세션을 서버에서 가졌을 때, 즉 문제를 직면 했을 때 전환해도 될 것 같다. 그럼에도 토큰이 익숙해서 사용하게 된다.
로드 밸런서의 스티키 세션 등 세션의 단점들을 충분히 해결할 수 있지 않을까?
세션 클러스터링, 동기화 등등 처리 비용에 대한 고민들 덕분에 결국 세션 스토리지는 독립된 서버로 발전하게 되었다.
다중 서버에서 세션 관리하기
다중 서버 환경에서 세션을 공유하고 관리하는 방법은 지속해서 발전해왔다. 해당 내용은 방대하며 짧게 요약할 수 없기 때문에 참고할만한 링크로 대체한다.
JWT의 경우 토큰 크기로 인해 트래픽의 부하가 커진다. (대략 50%라고 한다) 그런 부분에서 어떻게 생각하는가?
세션을 활용한 스케일 아웃은 학습 비용이 크다. 또한 많은 트래픽을 견딜 상황을 고려해야 한다. 오히려 여러 서버를 사용하는 상황에서는 학습 비용 측면에서 토큰 방식이 간편하며 쉽게 적용할 수 있지 않을까 생각한다.
세션을 사용해본 경험이 있는가?
대부분의 기능들이 구현되어 있어 편리하다. 하지만 처음으로 벽을 느낀 것은 비동기 처리로 인해 세션을 정상적으로 받아오지 못했다. 그 당시 해결 방법을 몰라 토큰 방식으로 전환했다.
토큰에 이점이 많은 것 같은데 왜 아직도 세션 & 쿠키 방식을 유지하는 서비스가 많을까?
이전에는 클라우드 방식이 아닌 온프레미스 방식을 주로 사용했다. 다중 서버 환경을 고려하지 않아도 되기 때문에 세션 & 쿠키 방식의 적용이 용이했을 것이다.
하지만 최근에는 일정하지 않은 사용자로 인해 수평 확장에 유리한 토큰 방식이 유리 해졌다고 생각한다.
JWT는 다들 쉽다고 생각한다. 몇 가지 예를 들면 멀티 로그인과 같은 상황에서 한 사람이 많은 토큰을 만들 수 있다. 이러한 경우 멀티 로그인에 대해 어떻게 막을 것인가? 멀티 로그인을 막으려면 결국 상태가 필요해지는 상황이 온다. 또한 토큰 기반을 잘 하려면 굉장히 어렵기 때문에 아직 변환하지 못한 회사들이 많다.
사실 JWT도 단순히 시크릿 키를 활용하여 암호화할 뿐이다. 단순히 암호화를 사용해서 대체해서 사용해도 되지 않을까?
JWT는 일종의 규약과 같다. 결국 이것을 설명하기 위한 레퍼런스가 많이 존재하며 토큰 인증에 대한 것들을 밑바닥 부터 만들 경우 많은 보수가 든다. 결국 기존에 제공하는 라이브러리를 잘 사용하는 것이 더 바람직하다 생각한다.
OAuth와 JWT의 차이는 무엇일까?
이전에는 외부에서 페이스북의 아이디와 비밀번호를 기반으로 요청을 전송했다. 이제는 토큰 정보를 가지고 활용할 수 있다. 즉 외부 서비스에서 페이스북의 토큰 정보를 기반으로 유저에 대한 정보를 조회할 수 있다.
OAuth도 버전이 존재한다. 이에 따라 구현이 달라질 수도 있다.
# 회고
해당 주제에 대해 준비할 때 단순히 세션 & 쿠키 방식과 토큰 방식의 특성과 차이에 대해서만 고민하였다. 하지만 생각보다 다양한 상황에서 고려해야 할 부분이 많았으며 어느정도의 트레이드 오프를 동반할 수 밖에 없는 상황들을 마주하게 되었다.
예를들어 가장 기본적인 토큰 방식은 stateless한 특성을 가진다. 하지만 멀티 로그인에 대한 대비를 위해서는 결국 서버 측에서 상태를 가지게 될 수 밖에 없는 구조를 야기하게 된다. 결국 토큰 방식으로 이룰 수 있는 이점들을 포기하게 될 것이다.
어떠한 인증 방식을 사용하든 정답이 없으며 각각의 장단점이 존재하게 된다. 단순히 토큰 방식을 사용하기 보다 왜 이것을 선택했고 어떠한 장단점이 있는지 인지하며 개발하는 것이 가장 중요하다고 느끼는 계기가 되었다.
# References
다중 서버 환경에서 Session은 어떻게 공유하고 관리할까? - 2편(Sticky Session, Session Clustering, Session Storage 분리) (opens new window)
토큰을 어디에 저장할까? (opens new window)
인증 방식 : Cookie & Session vs JWT (opens new window)