LESSON4. CGI에서 웹 애플리케이션으로
이번 장에서는 웹 애플리케이션의 기본 기술 중 하나인 쿠키(Cookie)와 세션(Session)에 대해서 배웠습니다. 이전까지 쿠키와 세션에 대해 들어보기는 했는데 제대로 잘 몰랐거든요. 그런데 책에 나온 예제를 가지고 직접 Fiddly를 통해 HTTP 통신하는 것들을 보면서 어느 정도 개념이 잡을 수 있었습니다! 그럼 책의 예제 바탕으로 이 두 개념에 대해 정리해볼게요.
우선 책에 나오는 예제 웹 애플리케이션을 소개하겠습니다. '피자 주문'하는 애플리케이션인데요. 구성 및 흐름은 다음과 같습니다. 이에 대한 자세한 설명은 생략하겠습니다.
위 어플리케이션은 PHP라는 언어가 사용되었는데요. 저도 PHP라는 언어에 대해 잘은 모르지만 서버쪽 부분에서 처리해야할 부분(아이디, 비밀번호 확인, 세션 및 쿠키 관리 등)을 HTML로 넘겨주는 것 같아요. 예를들어 '로그인 화면'에서 '상품 목록 화면'으로 넘어갈 때 'do_login.php'파일에서 아이디 및 비밀번호 확인을 하는데요. 넘겨준 파라미터의 값이 정확한지 확인하고 맞으면 그에 맞는 처리를 합니다. 그리고 여기서 '리다이렉트(Redirect)'라는 개념을 확인할 수 있는데요. 우선 'do_login.php'에서의 응답을 보겠습니다.
그림을 보면 우선 POST방식으로 아이디와 비밀번호를 넘겼기 때문에 메시지 부분으로 넘겨온 것을 볼 수 있습니다. 그리고 밑에 보면 Location 헤더Location : item_list.php
를 볼 수 있는데요. 이것은 아이디와 비밀번호가 일치했을 때 다시 넘겨줄 URL를 말합니다. 물론 실패했을 때는 'item_list.php'가 아닌 따로 만들어둔 '로그인실패.php'로 이동하겠죠. 그리고 좌측 상단에 302 상태가 있는데요. 이것은 어제 살펴보았듯이 요청된 리소스가 다른 URL로 이동했음을 말합니다. 다시 말하면 'do_login.php'에서 'item_list.php'로 넘겨줬다는 뜻인거죠. 여기서 리다이렉트의 개념을 정리하면 처음 요청한 URL과 다른 URL로 유도하는 것을 말합니다. 이 과정을 다시 정리하면 다음과 같습니다.
HTTP 통신에서 기본은 GET방식입니다. 맨 처음에 GET방식으로 'login.html'이 확인하는 것은 '보내도 될까?'라는 물음이었고 이에 대한 대답으로 200(OK)가 온 것입니다. 그리고 POST방식으로 아이디랑 비밀번호를 보냈고 이게 일치하여 'do_login.php'에서 'item_list.php'로 리다이렉트 한 것입니다.
그런데 여기서 문제가 하나 있습니다. 만약 주소창에서 바로 'item_list.php'로 접근하면 어떻게 될까요? 쿠키와 세션의 개념이 없는 상태에선 이런 접근이 가능합니다. 하지만 애플리케이션의 흐름상 로그인을 먼저 하고 'item_list.php'에 접근하는 것이 맞고 실제 로그인한 유저에 맞는 정보를 제공하기 위해선 실제 로그인이 먼저 되어야만 합니다. 그렇다면 어떻게 해결할 수 있을까요? 로그인 유무를 기록해보는 것은 어떨까요?
이에 대한 필요성으로 고안된 것이 쿠키(Cookie)입니다. 쿠키는 HTTP의 규격을 확장하여 웹 애플리케이션과 웹 브라우저 사이에서 정보를 교환할 수 있게 한 것입니다. 이렇게 말하면 잘 와닿지 않으니 먼저 조금 전 예시에서 이제는 쿠키를 적용한 것을 보여드리겠습니다.
쿠키가 적용되고 'item_list.php' URL에 바로 접근하면 아까와 달리 물품 리스트 창이 뜨지 않고 로그인 실패 화면이 뜹니다. 그리고 다시 제대로 로그인해서 들어가볼게요.
로그인 화면 이후 리다이렉트 되어 물품 리스트로 왔는데 헤더에 이전에 보지 못한 Cookie가 나오고 제가 입력한 아이디와 비밀번호가 보입니다. 그리고 제가 잠시 딴 사이트에 다녀왔다가 다시 'item_list.php'에 접근하니 아까와 그대로 접근이 됩니다.
이전과 달리 뭔가 변화가 생기긴 한 모양입니다. 먼저 이렇게 쿠키가 만들어진 이유는 로그인 하기 전 로그인 처리를 담당하는 'do_login.php'에서 기본 메서드를 이용하여 쿠키를 설정해줬기 때문입니다.
그림을 보면 쿠키를 설정하는 모습을 볼 수 있죠? 그리고 로그아웃을 하면 쿠키를 삭제하는데요. 'do_logout.php'에서 로그아웃을 담당하고 있는데 살펴보겠습니다.
이것 역시 'Set-Cookies'를 메서드를 통해 하고 있지만 " "
빈값을 넣고 유효날짜도 현재 시간보다 이전으로 설정하여 삭제한 것을 볼 수 있습니다. 이쯤되면 애플리케이션에서 쿠키가 어떻게 이용되고 있는지는 조금 알겠지만 그 전체적인 구조가 궁금한데요. 이에 대해 살펴보겠습니다.
웹 서버에서 웹 브라우저로 HTTP 응답의 헤더를 이용해 작은 정보를 보냅니다. 이건 '이름=값' 조합으로 표현되는데 이것을 쿠키(Cookie)라고 합니다. 이 쿠키를 로컬 웹브라우저 내에서 보관하고 있다가 같은 웹 서버에 접속하게 되면 전에 받았던 쿠키를 그대로 HTTP 요청 헤더에 넣어 보내는 것입니다. 그리고 '상품 목록 화면'에서는 이제는 쿠키의 값을 확인하는 것이죠. 쿠키의 내용을 가져온다음 쿠키로 가져온 아이디와 패스워드를 확인하고 그에 따른 처리를 하는 것입니다. 로그아웃을 하면 쿠키가 삭제 되었기 때문에 이전에 보았듯이 '상품 목록 화면'에서 쿠키의 값이 없어 로그인 실패화면으로 이동하는 것이죠. 정리하면 제대로 된 로그인을 성공하면 쿠키를 생성해 웹브라우저에 넘겨주고 그 쿠키값을 다시 리다이렉트된 곳에 전해주어 처리하는 것입니다.
근데 이렇게 쿠키를 사용하면 보안상 위험이 있습니다. 그 이유는 아까 보았듯이 쿠키에 아이디와 비밀번호가 그대로 노출되어 있습니다. 만약 저의 컴퓨터를 다른 사람이 사용하게 되면, 또 접근하게 되면 그들에게 아이디와 비밀번호가 유출될 수도 있는 것입니다. 그렇게 좀 더 안전하게 많은 정보를 보존하게 방법으로 고안된 것이 세션(Session)입니다.
책에서 은행 업무를 세션 업무로 비유를 했는데요. 참 이해하기 쉬웠던 것 같아요. 저도 따라서 한번 설명해볼게요. 먼저 은행에 두 사람이 기다리고 있고 두 사람이 계좌를 만든다고 가정해봅시다. 계좌를 만들기 위해 필요한 절차는 총 3가지(계좌 개설 신청 접수, 계좌 개설 처리 중, 계좌 개설 완료) 입니다. 먼저 온 사람이 개설 신청을 한 후 기다렸다가 처리가 끝나면 받아갈 수 있습니다. 그리고 다음에 온 사람도 마찬가지이구요. 지금은 사람이 몇 명 없어서 그렇지만 사람이 엄청 많아지면 개개인이 어디까지 진행했는지 알기 쉽지 않을 것입니다. 그래서 은행에서 관리표를 만들 수 있습니다. 다음과 같이요.
은행의 경우 이러한 관리표를 이용하였지만 웹애플리케이션은 HTTP를 통해 관리를 합니다. 그리고 은행에서 절차가 총 3가지 이듯이 저희 웹애플리케이션은 '로그인 → 주문할 피자 선택 → 주문 확인 → 로그아웃' 절차가 필요하고 이에 대한 관리를 해주면 됩니다. 이와 같은 일련의 처리 흐름을 세션(Session)이라고 합니다.
이제는 세션이 무엇인지에 대해 알아봤으니 쿠키의 한계를 어떻게 극복했는지 살펴봅시다. 쿠키는 기억할 수 있는 정보량의 한계(아이디와 비빌번호 정보만 기억)와 보안 측면에서 문제점이 있었습니다. 하지만 세션을 이용하면 이 두 가지를 모두 극복할 수 있습니다. 아까 은행에서 만든 관리표와 같이 우리 웹애플리케이션 절차 및 정보가 담겨져있는 상태 테이블을 웹 서버가 가지고 있다면 어떨까요? 그리고 접수번호 대신 특정 ID(이것을 세션 ID, Session ID 라고 합니다)를 부여하는 것이죠. 그렇게 되면 모든 절차를 표시해놓은 표를 웹 서버에서 들고있으니 세션ID만 알면 아이디와 비빌번호 정보 뿐 아니라 현재 웹애플리케이션 내 진행상황까지 알 수 있고 상태 테이블 내에 아이디 및 로그인 상태를 기록해두면 굳이 쿠키로 아이디랑 비밀번호를 설정해 보안상 위험을 안고갈 필요도 없습니다. 세션 ID를 이용한 세션 관리를 다음과 같이 될 수 있는 것이죠.
그럼 이런 의문이 들 수 있겠죠. 세션ID를 이용하여 각 웹 클라이언트를 파악하고 그들의 진행상황을 파악한다음 그에 따른 처리를 할 수 있지만 그럼 어떻게 세션 ID를 전달하는가? 이 때 사용될 수 있는데 '쿠키'입니다. 아까는 아이디와 비밀번호를 쿠키로 하는 바람에 보안상 위험이 있었지만 세션ID를 쿠키로 생성하는 것이죠(쿠키 속에 정보 자체를 저장하는 것과 세션ID만을 저장하는 것은 큰 차이가 있습니다!).
위 흐름대로 하면 'do_login.php'에서 세션ID를 생성해 쿠키에 저장하고 그것을 웹 클라이언트로 보낸다음 세션 ID를 담은 쿠키를 가지고 있습니다. 그리고 이후엔 그 쿠키를 이용하여 서버에 전해줘 세션 ID에 맞는 처리가 가능한 것이죠.
실제 'do_login.php'에서 생성한 세션ID를 쿠키에 저장하는 모습을 볼 수 있습니다.
그리고 이 세션ID를 이용하여 상품 목록 화면에 접근할 수 있는 것이구요. 그렇기 때문에 제가 피자 쇼핑을 하고 있다가 창을 닫아버려도 다시 그 URL로 가게되면 이전까지 진행했는 곳으로 바로 접근이 가능합니다.
실제 장을 다보고 창을 껐지만 세션과 쿠키를 이용하여 위와 같은 화면으로 바로 접근이 가능하였습니다. 만약 쿠키에 다른 세션ID도 저장되어 있다면 그 세션ID 상태에 맞는 접근이 가능합니다. 쿠키 관리가 별개로 되고, 웹 서버는 별개의 클라이언트로 식별하기 떄문입니다.
이로써 쿠키와 세션을 모두 살펴보았습니다. 어려웠나요? 제가 앞으로 이런 것도 구현할 수 있을거라 생각하니 참 기대되네요. 그럼 오늘은 여기까지!
'Book > programming' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] 03장. 영속성 관리 (0) | 2018.12.18 |
---|---|
프로가 되기 위한 웹기술 입문3 (2) | 2018.11.09 |
프로가 되기 위한 웹기술 입문1 (0) | 2018.11.07 |
스프링 입문을 위한 자바 객체지향의 원리와 이해6 (2) | 2018.10.27 |
스프링 입문을 위한 자바 객체지향의 원리와 이해5 (0) | 2018.10.21 |