웹 서비스는 대부분 사용자별로 맞춤형 서비스를 제공합니다. 사용자의 정보를 담을 수 있는 '계정'을 만들기 위해 먼저 회원가입을 요구하고, 해당 계정의 활동내역을 차곡차곡 저장해서 나중에 활용할 수 있도록 합니다. 시청 내역을 가지고 새로운 영상을 추천해 주거나, 쇼핑할 때마다 적립해 주었던 포인트를 가지고 새로운 상품을 구입할 수 있도록 해주는 것이죠.
사용자는 자신이 계정의 소유자임을 인정받기 위해 서버에 가입할 때 기재했던 아이디와 패스워드 정보를 넘겨줘야 합니다. 이 행위를 로그인이라고 합니다. 좀 더 포괄적인 의미에서 인증(Authentication)이라고 할 수도 있습니다. 서버에서는 사용자가 제출한 아이디와 패스워드 정보를 DB에 저장된 것과 대조합니다. 두 가지 정보가 서로 일치한다면 사용자에게 해당 계정으로 접속해서 서비스를 이용할 수 있는 권한을 부여해줍니다. 이것을 인가(Authorization)라고 합니다.
그리고 이 권한은 페이지 이동이 발생하거나 사용자가 로그인이 필요한 다른 행동을 할 때도 계속 유지되어야 합니다. 언제까지? 로그아웃할 때까지!
권한을 부여하는 방법은 어딘가에 로그인 상태를 유지하는데에 필요한 사용자의 정보를 저장해 두는 것입니다. 우리는 어디에 저장할 것인지 그리고 이것을 어떻게 구현할 것인지를 고민해야 하는데, 이때 쿠키, 세션, 토큰 같은 기술들을 활용하게 됩니다. 이 세 가지는 같이 소개되는 경우가 많지만, 엄밀히 말해서 서로 반대되는 개념은 아닙니다.
쿠키
쿠키를 이해하려면 먼저 HTTP에 대해 이해할 필요가 있습니다. HTTP는 stateless, 즉 상태를 저장하지 않습니다. 연결이 1회성으로 이루어지기 때문에 연결이 종료되면 정보가 모두 날아가게 됩니다.
만약 쿠키가 개발되지 않은 원시 상태에서 HTTP 통신을 이용해 로그인을 시도하는 사용자가 있다면 이렇게 될 겁니다.
사용자가 로그인 요청을 보내면 서버와 HTTP에 의한 연결이 이루어집니다. 서버에서는 로그인 요청을 허용할 것인지 확인한 다음 로그인된 상태의 페이지를 응답으로 보내주고 사용자는 로그인에 성공한 상태의 화면을 보게 됩니다.
다만, 응답이 완료되면 연결이 끊어지기 떄문에 특정 사용자가 로그인 중이라는 정보도 날아갑니다. 방금 로그인에 성공한 사용자가 메일을 보려고 메일 아이콘을 클릭한다면 그 순간 새로운 페이지로의 연결 요청을 보내게 되죠. 서버에서는 지금 요청을 보내고 있는 사용자가 아까 그 사람이라는 사실을 알 수가 없기 때문에 부적절한 접근이라면서 로그인 페이지로 돌려보내게 될 겁니다.
그러면 사용자는 이미 로그인을 했는데 뭔가를 하려고 하면 다시 로그인하라고 하는 무한루프에 빠지면서 깊은 빡침을 느끼게 됩니다.
이런 무상태성이라는 HTTP 통신의 특징 때문에 로그인한 사용자에 대한 정보를 어디엔가는 저장을 해두어야 하고, 이를 위해서 등장한 개념이 바로 쿠키입니다.
쿠키는 브라우저가 가지고 있는 작은 데이터 조각입니다. 키-값의 형태로 데이터를 보관하죠. HTTP 통신과 관계없이 브라우저가 실행되는 동안 쿠키가 계속 살아있기 때문에 사용자의 로그인 여부를 체크할 때 쿠키를 활용할 수 있습니다. 다시 말해서 쿠키는 전역변수와 유사하게 사용자의 상태를 계속 저장할 수 있는 공간이라고 할 수 있습니다.
브라우저를 열고 개발자 도구(F12) > 네트워크 > 쿠키로 들어가보면 지금 접속한 웹 페이지의 쿠키를 직접 까볼 수 있습니다.
네이버에 로그인하게 되면 NID_*** 라는 이름의 값들이 생긴 것을 확인할 수 있습니다. NID_AUT는 auth라는 의미인 듯하고 NID_SES는 session을 의미하는 것 같죠? 브라우저가 종료되거나 사용자가 쿠키 삭제를 하기 전까지는 요청을 보낼 때마다 쿠키가 헤더에 포함되어 제가 네이버 회원임을 보증해 줍니다.
쿠키만 가지고도 로그인 상태를 계속 유지하려는 우리의 목적을 달성할 수 있습니다. 서버에서는 헤더에 포함된 쿠키를 확인하여 어떤 회원의 정보를 보여주면 되는 지를 알 수 있게 됩니다. 하지만 쿠키는 완벽한 해결책이 아닙니다. 쿠키는 클라이언트가 들고 있는 것이므로, 보안에 취약하다는 문제점을 가지고 있습니다. 여러분도 크롬 확장 프로그램 하나만 설치하면 쿠키를 생성하거나 값을 수정할 수 있습니다. 제가 다른 사람의 쿠키를 탈취한 다음, 그 쿠키의 정보를 헤더에 포함시켜 서버로 요청을 보내면 서버는 저를 쿠키의 원래 소유자로 인식하게 됩니다.
세션
쿠키가 저장소를 의미하는 반면, 세션은 시간적 관념을 나타냅니다. session은 회의, 기간이라는 의미를 가지고 있습니다. IT 세상에서의 세션은 사용자가 처음 접속한 뒤 접속을 종료하기까지의 기간, 연결되어 있는 상태를 의미합니다. 이 기간 동안에 어떻게 정보를 저장하고 관리할 것이냐 하는 문제까지 포함해서 세션이라고 하기도 합니다. '쿠키 대신 세션을 사용한다'라는 표현은 후자의 의미로 사용된 것이죠. 그리고 통상적으로 세션 방식, 세션 기반 인증이라고 하는 것은 접속 중인 사용자의 정보를 서버에 있는 세션 저장소에 보관하는 방식을 일컫는 말로 사용되고 있습니다.
작동 원리는 다음과 같습니다.
서버는 새로운 사용자가 찾아오면 방을 하나 마련해줍니다. 그리고 열쇠를 사용자에게 넘겨줍니다. 열쇠의 이름은 세션 아이디입니다. 사용자는 열쇠를 보여주면 언제든지 서버와 방에 입장할 수 있습니다. 사용자에 관한 정보가 필요하면 서버는 열쇠를 통해서 방의 위치를 찾고, 방을 뒤집니다. 세션 아이디는 사용자의 쿠키에 저장됩니다.
정보에 대한 관리를 사용자에게 온전히 맡기는 대신, 열쇠만 쥐어주고 서버에서 직접 관리를 할 수 있어 조금 더 안전하다고 할 수 있습니다.
하지만 이 방식의 문제점은 요청이 들어올 때마다 방을 뒤져야 하기 때문에 요청이 많아질수록 점점 더 부하가 심해진다는 것입니다. 방수색 담당 직원을 더 뽑아야 하고 방이 가득 차면 또 새로운 건물을 지어야 합니다. 방이 많아지면 방을 찾는데도 더 많은 시간과 노력을 필요로 하게 됩니다.
토큰
토큰은 어떤 사실이나 정보를 나타내기 위한 상징, 징표를 의미합니다. 세션 아이디를 나눠주었듯 토큰을 사용자에게 나눠주는 점에서 열쇠 역할을 하는 것은 같습니다. 하지만 토큰에는 더 많은 기능이 탑재되어 있습니다. 토큰 안에 사용자의 정보가 포함되어 있기 때문에 매번 방 수색을 할 필요가 없습니다.
가장 널리 알려진 토큰으로 JWT 토큰이 있습니다. JWT(JSON Web Token)는 JSON 형태로 작성된 데이터를 암호화한 토큰입니다. JWT 토큰에 관한 자세한 내용은 다음 포스트에서 소개하도록 하겠습니다.
'Computer Science > Web & Network' 카테고리의 다른 글
HTTP 메서드 해부하기(1) - GET vs POST (0) | 2023.05.26 |
---|---|
[HTTP] User-Agent를 읽는 법 (0) | 2023.05.02 |
TCP/IP 4계층 모델은 어떻게 사용될까? (0) | 2023.03.16 |
OSI 7계층 이해하기 (2) | 2023.02.17 |
네트워크 프로토콜의 의미, 요소, 기능 (0) | 2023.02.14 |
댓글