관리 메뉴

거니의 velog

(22) 쿠키와 세션 알아보기 2 본문

Java_Servlet

(22) 쿠키와 세션 알아보기 2

Unlimited00 2023. 8. 29. 18:33

3. 쿠키를 이용한 웹 페이지 연동 기능

* 이번에는 웹 페이지끼리 정보를 공유하는 기능 중 쿠키를 이용하는 기능에 대해 알아보자.

* 쿠키(Cookie)란 웹 페이지들 사이의 공유 정보를 클라이언트 PC에 저장해 놓고 필요할 떄 여러 웹 페이지들이 공유해서 사용할 수 있도록 매개 역할을 하는 방법이다.

* 쿠키의 특징은 다음과 같다.

- 정보가 클라이언트 PC에 저장된다.

- 저장 정보 용량에 제한이 있다(파일 용량은 4kb).

- 보안이 취약하다.

- 클라이언트 브라우저에서 사용 유무를 설정할 수 있다.

- 도메인당 쿠키가 만들어진다(웹 사이트당 하나의 쿠키가 만들어진다).

* 쿠키는 클라이언트 PC에 정보를 저장해서 사용하므로 보안에 취약하다. 따라서 쿠키를 이용한 방법은 주로 보안과 무관한 경우에 한해 사용한다. 예를 들어 우리가 웹 페이지를 방문했을 때 어떤 팝업창이 나타나면 '오늘은 더 이상 보지 않기'를 체크하는데, 이처럼 팝업창이 나타나지 않게 하는 경우 등에 사용한다.

<쿠키의 종류>

속성 Persistence 쿠키 Session 쿠키
생성 위치 파일로 생성 브라우저 메모리에 생성
종료 시기 쿠키를 삭제하거나 쿠키 설정 값이 종료된 경우 브라우저를 종료한 경우
최초 접속 시
전송 여부
최초 접속 시 서버로 전송 최초 접속 시 서버로 전송되지 않음
용도 로그인 유무 또는 팝업창을 제한할 때 사이트 접속 시 Session 인증 정보를 유지할 때

* Persistence 쿠키는 클라이언트에 파일로 정보를 저장하는 기능을 한다. 파일로 생성된 쿠키는 사용자가 만료 시간을 지정할 수 있는 반면에 Session 쿠키는 브라우저가 사용하는 메모리에 생성되는 쿠키이다. 브라우저가 종료되면 메모리의 Session 쿠키도 자동으로 소멸된다. Session 쿠키는 다음에 배우는 Session 기능과 같이 사용된다.

* 그럼 실제로 클라이언트 PC에서 쿠키 파일이 생성되는 위치를 확인해 보자. 이미 여러 웹 사이트에서 사용하는 쿠키가 생성된 것을 볼 수 있다.

1. 윈도우 탐색기를 열고 C:\Users\사용자이름\AppData\Local\Google\Chrome\User Data\Default\Cache\Cache_Data로 이동하면 크롬에서 사용하는 쿠키 파일이 보일 것이다.


(1) 쿠키 기능 실행 과정

* 클라이언트 브라우저가 웹 서버에 요청하면 어떻게 쿠키가 생성되는지 살펴보자.

* 브라우저에서 웹 사이트에 최초 접속하면 웹 서버에서 쿠키를 생성해 클라이언트로 전송한다. 그리고 브라우저는 쿠키를 파일로 저장한다. 이후 다시 접속해 서버가 브라우저에게 쿠키 전송을 요청하면 브라우저는 쿠키 정보를 서버에 전송하고 서버는 쿠키 정보를 이용해서 작업을 한다.

(1) 브라우저로 사이트에 접속한다.

(2) 서버는 정보를 저장한 쿠키를 생성한다.

(3) 생성된 쿠키를 브라우저로 전송한다.

(4) 브라우저는 서버로부터 받은 쿠키 정보를 쿠키 파일에 저장한다.

(5) 브라우저가 다시 접속해 서버가 브라우저에게 쿠키 전송을 요청하면 브라우저는 쿠키 정보를 서버에 넘겨준다.

(6) 서버는 쿠키 정보를 이용해 작업을 한다.

(2) 쿠키 API

* 실제로 서블릿에서 쿠키 기능 사용 시 이와 관련된 API에 대해 알아보자. 쿠키는 Cookie 클래스 객체를 생성하여 정보를 저장한 후 서버에서 클라이언트로 전송해 파일로 저장된다. 쿠키 관련 API의 특징은 다음과 같다.

- javax.servlet.http.Cookie 를 이용한다.

- HttpServletResponse의 addCookie() 메서드를 이용해 클라이언트 브라우저에 쿠키를 전송한 후 저장한다.

- HttpServletRequest의 getCookie() 메서드를 이용해 쿠키를 서버로 가져온다.

<쿠키 클래스의 여러 가지 메서드>

메서드 설명
getComment() 쿠키에 대한 설명을 가져온다.
getDomain() 쿠키의 유효한 도메인 정보를 가져온다.
getMaxAge() 쿠키 유효 기간을 가져온다.
getName() 쿠키 이름을 가져온다.
getPath() 쿠키의 디렉터리 정보를 가져온다.
getValue() 쿠키의 설정 값을 가져온다.
setComment(String) 쿠키에 대한 설명을 설정한다.
setDomain(String) 쿠키의 유효한 도메인을 설정한다.
setMaxAge(int) 쿠키 유효 기간을 설정한다.
setValue(String) 쿠키 값을 설정한다.

* 쿠키 생성 시 setMaxAge() 메서드 인자 값의 종류를 지정해서 파일에 저장하는 Persistence 쿠키를 만들거나 메모리에만 저장하는 Session 쿠키를 만들 수 있다. 즉, setMaxAge() 메서드를 이용한 쿠키 저장 방식은 다음 두 가지로 나눌 수 있다.

* 인자 값으로 음수나 setMaxAge(0 메서드를 사용하지 않고 쿠키를 만들면 Session 쿠키로 저장된다.

* 인자 값으로 양수를 지정하면 Persistence 쿠키로 저장된다.


(3) 서블릿에서 쿠키 사용하기

* 서블릿에서 쿠키 API를 이용해 직접 쿠키를 만들어 보자.

1. GetCookieValue, SerCookieValue 클래스 파일을 준비한다.

2. SetCookieValue 클래스를 다음과 같이 작성한다. Cookie 객체를 생성한 후 쿠키 이름을 cookieTest로 값을 저장한다. 그리고 setMaxAge(0 메서드에 쿠키 유효 시간을 24시간으로 설정한다. 그런 다음 response의 addCookie() 메서드를 이용해 생성된 쿠키를 브라우저로 전송한다.

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/set")
public class SetCookieValue extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		Date d = new Date();
		Cookie c = new Cookie("cookieTest", URLEncoder.encode("JSP프로그래밍입니다.", "utf-8")); // Cookie 객체를 생성한 후 cookieTest 이름으로 한글 정보를 인코딩해서 쿠키에 저장한다.
		c.setMaxAge(24 * 60 * 60); // 유효 기간을 설정한다. 24시간 기준.
		//c.setMaxAge(-1);  //세션 쿠키를 생성합니다.
		response.addCookie(c); // 생성된 쿠키를 브라우저로 전송한다.
		out.println("현재시간 : " + d);
		out.println("<br> 문자열을 Cookie에 저장합니다.");
	}

}

3. GetCookieValue 클래스를 다음과 같이 작성한다. 두 번째 서블릿 요청 시에는 request의 getCookies() 메서드를 호출해 브라우저로부터 쿠키를 전달받는다. 그리고 전달된 쿠키에서 저장할 때 사용한 이름인 cookieTest로 검색해 값을 가져온다.

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/get")
public class GetCookieValue extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		  response.setContentType("text/html;charset=utf-8");
		  PrintWriter out = response.getWriter();
		  Cookie[] allValues = request.getCookies(); // request의 getCookies() 메서드를 호출해 브라우저에게 쿠키 정보를 요청한 후 쿠키 정보를 배열로 가져온다.
		  for(int i=0; i<allValues.length;i++){
		     if(allValues[i].getName().equals("cookieTest")){
		      out.println("<h2>Cookie 값 가져오기 : " + URLDecoder.decode(allValues[i].getValue(), "utf-8"));
		     }
		  } // 배열에서 저장할 때 사용한 쿠키 이름인 cookieTest로 검색해 쿠키 값을 가져온다.
	}

}

4. 우선 set으로 첫 번째 서블릿을 요청한다. 쿠키에 cookieTest 이름으로 문자열을 저장한다.

- http://localhost:8090/pro09/set

5. get으로 두 번째 서블릿을 요청하여 cookieTest로 쿠키 값을 가져와 브라우저에서 출력한다.

- http://localhost:8090/pro09/get


(4) 세션 쿠키 사용하기

* 다음은 쿠키를 파일에 저장하는 것이 아닌, 브라우저가 사용하는 메모리에 저장하는 Session 쿠키를 만들어 보자.

1. 다음과 같이 Cookie의 setMaxAge() 메서드를 이용해 유효 시간을 -1로 설정하면 세션 쿠키가 생성된다.

package sec02.ex01;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/set")
public class SetCookieValue extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		Date d = new Date();
		Cookie c = new Cookie("cookieTest", URLEncoder.encode("JSP프로그래밍입니다.", "utf-8")); // Cookie 객체를 생성한 후 cookieTest 이름으로 한글 정보를 인코딩해서 쿠키에 저장한다.
//		c.setMaxAge(24 * 60 * 60); // 유효 기간을 설정한다. 24시간 기준.
		c.setMaxAge(-1);  // 유효 시간을 음수로 지정하여 Session 쿠키를 생성한다.
		response.addCookie(c); // 생성된 쿠키를 브라우저로 전송한다.
		out.println("현재시간 : " + d);
		out.println("<br> 문자열을 Cookie에 저장합니다.");
	}

}

2. 톰캣을 재실행한다. 출력 결과는 앞의 예제와 같다.


(5) 쿠키 이용해 팝업창 제한하기

* 쿠키를 이용해 팝업창을 제한하는 기능을 구현해 보자. 팝업창 제어는 서버에서 쿠키를 다루지 않고 자바스크립트를 이용해 쿠키에 직접 접근한다.

1. popUp.html, popUpTest.html 이렇게 두 개의 html 파일을 준비한다.

2. 먼저 popUpTest.html을 다음과 같이 작성한다. 웹 페이지가 브라우저에 로드될 때 pageLoad() 함수를 호출한 후 쿠키에 접근해 팝업창 관련 정보를 가져온다. getCookieValue() 함수를 호출하여 쿠키 이름 notShowPop의 값이 true가 아니면 팝업창을 나타내고, notShowPop의 값이 true이면 팝업창을 나타내지 않는다.

<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <title> 자바스크립트에서 쿠키 사용 </title>
        <script type="text/javascript">
            // 페이지 로드 이벤트 처리
            window.onload = pageLoad; // 브라우저에서 웹 페이지가 로드될 때 pageLoad() 함수를 호출하여 실행한다.

            function pageLoad() {
                // 저장된 쿠키 읽어오기
                notShowPop = getCookieValue(); // notShowPop의 쿠키 값을 getCookieValue()를 호출하여 얻는다.
                if (notShowPop != "true") {
                    window.open("popUp.html", "pop", "width=400,height=500,history=no,resizable=no,status=no,scrollbars=yes,menubar=no");
                } // notShowPop의 값이 true가 아니면 팝업창을 나타낸다.
            }

            // 쿠키 읽어오는 함수
            function getCookieValue() {
                var result = "false";
                // 쿠키 여부 확인
                if (document.cookie != "") {
                    cookie = document.cookie.split(";"); // document의 cookie 속성으로 쿠키 정보를 문자열로 가져온 후 세미콜론(;)으로 분리해 각각의 쿠키를 얻는다.
                    for (var i = 0; i < cookie.length; i++) {
                        element = cookie[i].split("=");
                        value = element[0];
                        value = value.replace(/^\s*/, ''); // 정규식을 이용해 쿠키 이름 문자열의 공백(\s)을 제거한다.
                        if (value == "notShowPop") {
                            result = element[1];
                        } // 쿠키 이름이 notShowPop이면 해당하는 쿠키 값을 가져와 반환한다.
                    }
                }
                return result;
            }

            function deleteCookie() {
                document.cookie = "notShowPop=" + "false" + ";path=/; expires=-1";
            } // '쿠키삭제' 클릭시 호출된다. notShowPop 쿠키 값을 false로 설정한다.
        </script>
    </head>

    <body>
        <form>
            <!-- 쿠키를 삭제하는 버튼 -->
            <input type="button" value="쿠키삭제" onclick="deleteCookie()"> 
        </form>
    </body>

</html>

3. popUp.html 에서는 '오늘 더 이상 팝업창 띄우지 않기'에 체크하면 자바스크립트 함수인 setPopUpStart() 함수를 호출해 notShowPop의 값을 true로 설정하여 재접속 시 팝업창을 나타내지 않도록 설정한다.

<html lang="ko">

    <head>
        <meta charset="UTF-8">
        <script type="text/javascript">
            function setPopUpStart(obj) {
                if (obj.checked == true) {
                    var expireDate = new Date();
                    var days = 1;
                    expireDate.setDate(expireDate.getDate() + days); // 쿠키 유효 시간을 하루로 설정한다.
                    document.cookie = "notShowPop=" + "true" + ";path=/; expires=" + expireDate.toGMTString(); // '오늘 더 이상 팝업창 띄우지 않기'에 체크하면 notShowPop 쿠키 값을 true로 설정하여 재접속시 팝업창을 나타내지 않는다.
                    window.close();
                }
            }
        </script>
    </head>

    <body>
        알림 팝업창입니다.
        <br><br><br><br><br><br><br>
        <form>
            <input type="checkbox" onclick="setPopUpStart(this)"> 오늘 더 이상 팝업창 띄우지 않기
        </form>
    </body>

</html>

4. 브라우저에 최초 접속 시 팝업창을 나타낸다.

- http://localhost:8090/pro09/popUpTest.html

5. '오늘 더 이상 팝업창 띄우지 않기'에 체크하고 재요청하면 더 이상 팝업창이 나타나지 않는다.

6. 쿠키삭제를 클릭한 후 재요청하면 다시 팝업창이 나타난다.