쿠키와 세션 - 쿠키

코코·2020년 8월 7일
0

Servlet/JSP

목록 보기
9/20
post-thumbnail

세션 트래킹

HTTP프로토콜 방식으로 통신하는 웹 페이지는 서로 어떤 정보도 공유하지 않는다.

쿠팡 메인 페이지에서 로그인하고 주문 페이지에서 또 다시 로그인하지 않아도 되는 이유는 세션 트래킹Session Tracking이라는 웹 페이지 연결기능을 구현했기 때문이다.

HTTP프로토콜은 서버-클라이언트 통신 시 스테이트리스stateless방식으로 통신한다. 브라우저에서 새 웹 페이지를 열면 이전 웹 페이지에 대한 어떤 정보도 새 웹페이지는 알 수 없다.
stateless란, 각각 웹 페이지 정보, 상태를 다른 웹페이지와 공유하지 않는 방식을 말한다.
따라서 웹 페이지를 서로 연결하기 위해 세션 트래킹을 이용해야 한다.

웹 페이지를 연동하는 방법은 몇 가지가 있다.

  • hidden 태그
  • URL Rewriting
    GET방식으로 URL뒤에 정보를 붙이는 방식
  • 쿠키
    클라이언트 PC의 Cookie파일에 정보를 저장한 후 웹 페이지들이 공유한다.
  • 세션
    서버 메모리에 정보를 저장한 후 웹 페이지들이 공유한다.

쿠키를 이용한 연동

쿠키Cookie는 웹 페이지들끼리 공유하는 정보를 클라이언트 PC에 저장해두고, 필요할 때 사용할 수 있도록 매개하는 역할을 한다.

쿠키의 특징

  • 정보가 클라이언트 PC에 저장
  • 저장 정보 용량 제한
  • 보안 취약
  • 클라이언트 브라우저에서 사용 유무 설정 가능
  • 도메인당 쿠키가 만들어진다.

쿠키의 종류

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

Persistence쿠키는 파일로 정보를 저장한다. 파일로 생성된 쿠키는 사용자가 만료 기한을 정할 수 있다. 반면 Session쿠키는 브라우저가 사용하는 메모리에 생성된다. 따라서 브라우저를 종료하면 Session쿠키도 함께 소멸한다.

쿠키 생성 과정

  1. 브라우저로 사이트에 접속한다.
  2. 서버는 정보를 저장한 쿠키를 생성한다.
  3. 생성한 쿠키를 브라우저로 전송한다.
  4. 브라우저는 서버로부터 받은 쿠키를 파일에 저장한다.
  5. 재접속 시, 서버는 브라우저에게 쿠키를 요청하고, 브라우저는 서버로 쿠키를 보낸다.
  6. 서버는 쿠키를 이용해서 작업한다.

javax.servlet.http.Cookie

서블릿에서 이용할 수 있는 쿠키 API다.

  • HttpServbletResponse의 addCookie()를 이용해서 클라이언트 브라우저로 쿠키를 전송한다.
  • HttpServletRequest의 getCookie()를 이용해서 쿠키를 서버로 가져온다.

Cookie클래스의 메서드

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

setMaxAge()를 사용하지 않거나 인자가 음수일 경우 Session쿠키 그 외는 Persistence쿠키다.

SetCookieValue.java

@WebServlet("/scook")
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 date = new Date();
		
		//쿠키 객체를 생성한 후, cookTest라는 이름으로 한글 정보를 인코딩해서 쿠키에 저장한다.
		Cookie cookie = new Cookie("cookieTest", URLEncoder.encode("JSP PROGRAMMING", "utf-8"));
		
		cookie.setMaxAge(24*60*60); //유효기간을 1일로 한다.

		//응답에 쿠키를 포함한다.
		response.addCookie(cookie);
		
		out.println("현재 시간 : " + date);
		out.print("현재시간을 쿠키로 저장한다.");
	}
}

GetCookieValue.java

@WebServlet("/gcook")
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();
		
		//request의 getCookie()로 요청한 쿠키 정보를 배열로 받는다.
		Cookie[] allValues = request.getCookies();
		
		//
		for(int i=0; i<allValues.length; i++) {
			if(allValues[i].getName().equals("cookieTest")) {
				out.println("<h2>Cookie Value : "+ URLDecoder.decode(allValues[i].getValue(),"utf-8")+"</h2> ");
			}
		}
	}
}


브라우저에서 /scook 호출

F12 개발자 도구를 열어서 Application탭에서 쿠키가 생성되었다는 것을 확인한다.

/gcook 호출

저장된 cookie를 HttpServletRequest의 getCookie()로 불러와서 읽었다.
쿠키 이름, 값, 유효기간까지 잘 유지 되어 전달 받은 것을 확인한다.

만약 쿠키를 지운다면?

읽어들일 Cookie가 없으므로 NullPointException이 발생한다
500번대 에러는 서버에서 예외가 발생했을 때 나는 에러다.

위 예제는 setMaxSize()를 설정했고, 음수가 아니므로 Persistence쿠키다.

SetCookieValue.java에서 설정해준 setMaxSize()의 인자를 음수로 바꾸거나, 지우면 Session Cookie가 된다.

setMaxSize()를 지우고 다시 확인한 결과다. 'Session'이라고 날짜가 바뀌었다.

자바스크립트로 팝업창 제한하기

popupTest.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JS로 쿠키 제어하기</title>
</head>
<body>
	<form>
		<input type='button' value='쿠키 삭제' onclick="deleteCookie()">
	</form>
<script>

window.onload = () => {
	//notShowPop의 쿠키 값을 getCookieValue()를 호출하여 얻는다.
	notShowPop = getCookieValue();
	
	console.log(getCookieValue());
	console.log(typeof notShowPop);
	console.log(notShowPop !== 'true')
	
	
	//notShowPop이 true가 아니면 팝업창을 나타낸다.
	if(notShowPop !== 'true') {
		window.open("popUp.html","pop","width=400,height=500,history=no,"
				+"resizable=no,status=no,scrollbars=yes,menubar=no");
	}
} 

function getCookieValue() {
	var result = 'false';
	if(document.cookie!== '') {
		//document의 cookie속성으로 쿠키 정보를 문자열로 가져온 후 ';'를 구분자로하여 각각 쿠키를 얻는다.
		cookie = document.cookie.split(';');
		
		for(var i=0; i<cookie.length;i++) {
			element = cookie[i].split('=');
			value=element[0];
			//정규식을 이용해 쿠키 이름 문자열의 공백을 제거
			value=value.replace(/^\s*/,'');
			
			if(value==='notShowPop') {
				result = element[1];
			}
		} //for
	} // if
	return result;
} //getCookieValue()

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

popUp.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>알림 팝업창</h1>
<br><br>
<form>
	<input type='checkbox' onClick='setPopUpStart(this)'>오늘 더 이상 팝업창 띄우지 않기
</form>

<script>
	function setPopUpStart(obj) {
		if(obj.checked === true) {
			var expireDate = new Date();
			//쿠키의 유효 기간을 한 달로 설정한다.
			expireDate.setMonth(expireDate.getMonth() +1);
			//체크하면 notShowPop쿠키 값을 true로 설정하여 재접속 시 팝업창을 나타내지 않는다.
			document.cookie='notShowPop='+'true'+';path=/; expires='+expireDate.toGMTString();
			
			window.close();
		} 
	}
</script>
</body>
</html>

/popupTest를 호출하면 이렇게 팝업창이 나온다.
1.현재는 Value가 false다.
2.체크박스를 체크하고, 새로 고침한다.

Value가 true로 바뀌면서 팝업창이 뜨지 않는 것을 확인한다.

0개의 댓글