개요
소셜 네트워크 서비스 'AGORA'를 제작하면서 가장 먼저 개발한 기능은 회원가입/로그인 입니다. 혼자 사용하거나 모든 정보가 공개된 웹 어플리케이션이 아니라면 대부분의 웹 어플리케이션은 회원가입과 로그인 기능이 구현되어 있습니다. 이러한 인증 기능은 왜 필요할까요?
각각의 클라이언트는 웹 서비스에서 개별적인 컨텐츠를 소비합니다. 그러므로 Client에서 API를 요청하였을 때, 서버는 누구의 요청인지 정확하게 식별해야만 합니다. 즉, 서버는 각 클라이언트의 개인적인 정보들을 보관하고 이를 클라이언트의 요청에 맞추어 제공해야만 합니다. 이러한 과정 속에 '인증'(Authentication)이 이루어지지 않는다면 개인정보가 유출되거나 변조되는 등의 취약점이 발생할 수 있습니다.
지금부터 기본적이지만 중요한 기능인 '로그인'에 대해서 알아보겠습니다.
로그인에 대해 알아보기 전에 HTTP란 무엇일까?
HTTP는 클라이언트와 서버 사이에 이루어지는 요청/응답(request/response) 프로토콜이다. 예를 들면, 클라이언트인 웹 브라우저가 HTTP를 통하여 서버로부터 웹페이지나 그림 정보를 요청하면, 서버는 이 요청에 응답하여 필요한 정보를 해당 사용자에게 전달하게 된다.
Wikipedia 의 내용을 간단하게 요약하면 HTTP 는 클라이언트(브라우저)와 서버 사이의 의사소통 방식입니다. 이러한 HTTP 는 비연결성(Connectionless)과 무상태(Stateless)라는 특성을 가집니다. 비연결성이란 클라이언트가 요청(request)을 하고, 서버가 해당 요청에 적합한 응답(response)를 하게 되면 바로 연결을 끊는 성질을 의미합니다.
무상태(Stateless)
비연결적인 특성으로 연결이 해제됨과 동시에 서버와 클라이언트는 클라이언트가 이전에 요청한 결과에 대해서 잊어버리게 됩니다. 즉, 클라이언트가 이전 요청과 같은 데이터를 원한다고 하더라도 다시 서버에 연결을 하여 동일한 요청을 시도해야만 합니다.
HTTP는 이러한 특성으로 인해 'Stateless Protocol' 이라고 불리며, 독립적인 쌍의 요청과 응답을 처리함으로 단순하고, 상태를 저장해야 하는 서버의 부담을 감소시킬 수 있습니다.
HTTP가 비연결성과 무상태 라는 강력한 특성을 갖는 건 알겠는데 상태가 서버에 저장되어 있지 않는다면 '인증'은 어떻게 구현해야 할까요? 매번 클라이언트는 데이터베이스를 왕복하며 인증을 해야 하는 걸까요?
먼저 답을 하자면 'NO!' 입니다. 지금부터 이 방법에 대해 알아보겠습니다!
서로의 연결성과 상태 유지하지 않는 서버와 클라이언트가 로그인을 처리하려면 어떻게 해야할까?
로그인은 인증(Authentication) 의 한 방법입니다. 서비스를 사용하는 사람이 본인이 맞는지 확인하는 것을 인증이라고 합니다. 로그인 상태를 유지한다는 것은 인증상태를 유지한다는 것입니다.
필자가 공부한 책에서 로그인을 간단하게 정의한 내용입니다. 위 정의에도 명시되어 있듯이 로그인은 인증을 하고 일정 시간동안 인증상태를 유지해야만 합니다. HTTP 를 사용하는 입장에서 굉장히 난감한 상황입니다.
하지만 이를 해결하기 위한 방법 역시 존재합니다. 바로 쿠키와 세션을 사용하는 것입니다. 먼저 쿠키에 대해서 알아보겠습니다.
쿠키(Cookie)
쿠키는 웹 브라우저가 보관하는 데이터입니다. 웹 서버는 쿠키를 생성하여 웹 브라우저에 정보를 전송할 수 있습니다. 쿠키는 키-밸류 형태로 웹 브라우저의 쿠키 저장소에 저장됩니다. 서버로부터 쿠키를 전달받은 웹 브라우저는 이후 웹 서버에 요청을 보낼 때 쿠키를 헤더에 실어서 함께 전송합니다. 이를 이용하면 웹 서버와 클라이언트는 필요한 값을 공유하고 상태를 유지할 수 있습니다.
클라이언트에 보관된 쿠키는 유효기간 설정이 가능합니다. 유효기간을 설정하면 쿠키는 특정 시간이 지나면 자동으로 소멸합니다. 유효기간을 설정하지 않을 시에는 브라우저 종료와 함께 소멸합니다.
하지만 쿠키만으로 로그인을 구현하는 것은 한계가 있습니다. 쿠키는 네트워크를 통해 전달되기 때문에 중간에 쿠키를 탈취할 수 있다는 취약점이 있습니다. 이를 보완하고자 우리는 세션(Session) 을 사용합니다.
세션(Session)
세션도 마찬가지로 클라이언트의 상태를 저장할 수 있습니다. 쿠키와 다른 점은 쿠키는 각 브라우저의 별도 쿠키 저장소에 저장되는 반면에 세션은 서버에 저장이 됩니다.
웹 브라우저는 각각 별도의 세션을 갖습니다. 각 세션을 구분하기 위해 고유 ID 를 할당하고, 웹 서버는 각 브라우저에 세션 ID 를 전송합니다. 웹 브라우저는 웹 서버에 연결 시 매번 세션 ID 를 보내서 웹 서버가 어떤 세션을 사용할 지 알 수 있도록 합니다. 이 때, 웹 서버와 웹 브라우저가 세션 ID 를 주고받기 위해서 사용하는 것이 쿠키입니다. (Tomcat 에서 발급하는 쿠키의 Key 는 JSESSIONID 입니다.)
이를 종합하여 로그인이 이루어지는 과정을 보겠습니다. 우리는 로그인 정보를 웹 컨테이너 메모리의 세션 객체에 저장하게 되고, 클라이언트는 세션 ID를 전송하여 브라우저 고유 세션을 식별하게 됩니다. 이 후 세션 객체 내부에 로그인 여부를 확인할 수 있는 특정 속성이 존재하면 로그인한 것으로 판단할 수 있습니다.
아래 그림을 보면 클라이언트와 웹서버가 세션과 쿠키를 이용하여 어떻게 로그인 인증 절차를 가지는지 확인하실 수 있습니다.
정리해보기
1. HTTP 는 '비연결성'과 '무상태' 라는 특성을 지님으로 멀티 쓰레드 환경에서 웹 어플리케이션이 보다 많은 요청과 응답을 할 수 있도록 합니다.
2. 하지만 웹 어플리케이션은 상태를 유지해야 하는 서비스가 존재합니다. 이에 대표적인 서비스가 '로그인' 입니다.
3. '세션' 과 '쿠키' 를 사용하면 HTTP 의 특성의 한계를 극복하고 보다 쉽게 로그인을 구현할 수 있습니다.
참고
- 최범균의 JSP 2.3 웹프로그래밍, 2018년 10월 15일 6쇄 발행본
- "[HTTP\] HTTP 특성(비연결성, 무상태)과 구성요소 그리고 Restful API", victolee, 2020-05-10, https://tansfil.tistory.com/58
- "[Network] HTTP의 동작 및 HTTP Message 형식", Heee's Development Blog, 2020-05-09,
https://gmlwjd9405.github.io/2019/04/17/what-is-http-protocol.htmlhttps://gmlwjd9405.github.io/2019/04/17/what-is-http-protocol.html - "쉽게 알아보는 서버 인증 1편(세션/쿠키, JWT)", 이호연 블로그, 2020-05-11,
https://victorydntmd.tistory.com/286 - "Stateless and Connectionless HTTP Protocol", WAY2JAVA, 2020-05-08 ,
https://way2java.com/servlets/stateless-and-connectionless-http-protocol/
다음 포스팅에는!
'다중 서버 환경에서 세션을 어떻게 공유하고 관리할까?' 에 대해 알아보겠습니다!