본문 바로가기
WEB/JSP

쿠키와 세션

by 둥바 2022. 8. 3.

HTTP의 비연결성

- 웹 프로그램은 현재 페이지 -> 다른 페이지로 이동하면 현재 페이지에 저장된 값이 모두 소멸된다.

- 페이지 간의 연결을 해서 넘어갈 때 데이터를 유지할 수 있도록 하는 기법이 두 가지가 있는데 그것이 바로 쿠키와 세션이다. 이 같은 HTTP의 비연결성의 약점을 보완한 기법이지만 장단점이 존재한다.

 

- 쿠키(cookie)

- 우리가 생각하는 쿠키와 같다. 쿠키를 먹으면 부스러기(흔적)들이 나오는데, 이 같은 방문기록(부스러기) 등이 쿠키를 통해 저장된다.

- 클라이언트에 저장(웹 브라우저에 자료 저장)하기 때문에,

-> 단점으로는,

공유 PC 등과 같이 보안에 취약하고 쿠키 조작 및 변조가 가능하다.

따라서 공개되어도 상관없는 간단한 데이터들은 쿠키로 처리한다.

쿠키처리는 대부분 자바스크립트로 구현해야되며, 복잡한 코드로 작성해야한다.

 

-> 한 가지 장점이라면 클라이언트에 저장되니까 따라서 서버에 부하가 걸리지 않는다.

 

- 세션

- 서버에 저장되므로 보안이 우수하지만, 서버의 성능이 저하될 위험이 있다.

- 쿠키보다 코드 작성 방법이 보다 쉽다.

 

< 따라서 중요하지 않은 데이터는 쿠키로, 중요한 데이터라면 세션으로 처리하게 된다. >


쿠키

웹 브라우저마다 쿠키가 쌓이는 폴더는 다르다.

 

2) 쿠키의 생성 및 수정

쿠키는 클라이언트쪽에 데이터가 쌓이기 때문에 response객체로 다룬다. 응답헤더에 쿠키를 추가하는 것이다.

response.addCookie(new Coookie("쿠키변수명","값")); //("스트링","스트링") - Key,value 모두 스트링만 된다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>
<%@ page import="java.net.URLEncoder"  %>
<!-- 톰캣이 낮은 버전이라면, Encoder를 써줘야한다. -->
<%
//new Cookie("쿠키변수명","값"); 
//주의점 : 값은 String type만 가능하다.
Cookie cookie = new Cookie("id","kim");
Cookie cookie2 = new Cookie("pwd","1234");

//톰캣 하위 버전에서는 특수문자,한글 쓰면 에러나기 때문에 인코딩을 해야함.
//Cookie cookie3 = new Cookie("name",URLEncoder.encode("김철수","utf-8"));
Cookie cookie3 = new Cookie("name","김철수");
Cookie cookie4 = new Cookie("age","20");

response.addCookie(cookie);//응답헤더에 쿠키 추가
response.addCookie(cookie2);
response.addCookie(cookie3);
response.addCookie(cookie4);

//쿠키의 유효시간 설정
//cookie.setMaxAge(10);//10초후에 삭제됨

%>

쿠키가 생성되었습니다.<br>

쿠키를 쓰는 목적은 HTTP의 비연결성때문에 쓰는 것이니까, 
페이지를 만들어서 값이 넘어가는지 테스트해봅시다.

<a href="useCookie.jsp">쿠키확인</a>
</body>
</html>

 

<수정>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>
<% 
//쿠키 수정(value만 수정) - 생성자 활용
response.addCookie(new Cookie("id","park"));
%>
쿠키가 변경되었습니다.
<a href="useCookie.jsp">쿠키 확인</a>
</body>
</html>

 

 

 

3) 쿠키 읽는 것은 배열을 활용한다.

Cookie[] cookies = request.getCookies();

if(cookies!=null){

for문으로 돌려 처리}

 

cf) EL(Expression Language) 방식 : ${cookie.쿠키변수명.value} 만 하면 위의 자바 코드를 한 줄로 대체할 수 있다. 

 

4) 쿠키 변수는 String만 가능하기 때문에 특수문자, 한글을 사용하려고 한다면 인코딩을 시켜야한다. (톰캣 버전에 따라서 인코딩 처리를 해야하는데, 오래된 버전의 경우는 반드시 인코딩처리를 해주어야 한다.)

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>
<%
//쿠키는 클라이언트의 웹 브라우저에 저장된 쿠키값은 배열로 받는다.
Cookie[] cookies = request.getCookies();
if(cookies != null){
	for(int i=0;i<cookies.length;i++){
		out.println("쿠키이름 : " + cookies[i].getName());
		out.println(",쿠키 값: " + cookies[i].getValue()+"<br>");
	}
}
%>

<!-- EL(Expression Language 표현 언어)로 처리 : 여기서 $는 EL이며, 이는 자바코드의 일종이다.-->
아이디 : ${cookie.id.value}<br>
비번 : ${cookie.pwd.value}<br>
이름 : ${cookie.name.value}<br>
나이 : ${cookie.age.value}<br>


<a href="deleteCookie.jsp">쿠키 삭제용 페이지</a>
<a href="editCookie.jsp">쿠키 값 변경 페이지</a>
</body>
</html>

 

 

 

5) 쿠키 삭제

따로 삭제 전용 메소드가 없어서, 쿠키를 삭제하는 방법들은 다음과 같다.

1.Cookie cookie = new Cookie("name",""); //쿠키변수의 값을 빈 값으로 처리

2. cookie.setMaxAge(0); //쿠키 즉시 삭제(0초)

cookie.setMaxAge(-1); //브라우저를 닫으면 쿠키 삭제

와 같이 쿠키의 유효기간을 초단위로 설정한다.

3. response.addCookie(cookie); //마지막으로 addCookie함수로 쿠키를 처리할 수도 있다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>
<%
//전체 쿠키 삭제
Cookie[] cookies = request.getCookies();
if(cookies != null){
	for(int i=0;i<cookies.length;i++){
		cookies[i].setMaxAge(0);
		//만료
		response.addCookie(cookies[i]);
		//응답헤더에 이 쿠키를 추가해줌
	}
}


//개별 쿠키 삭제

/*
Cookie cookie = new Cookie("id","");
cookie.setMaxAge(0);
response.addCookie(cookie);
*/

%>



쿠키가 삭제되었습니다.
<a href="useCookie.jsp">쿠키확인</a>
</body>
</html>

 

위와 같은 작업들을 공용으로 보다 편하게 하기 위해 따로 자바파일로 만드는 방법도 있다.

src/main/java - common 폴더 아래에 Util.java 파일을 만든다.

package common;

import javax.servlet.http.Cookie;

public class Util {
	public static String getCookie(Cookie[] cookies, String name) {
		String result = "";
		if(cookies!= null) {
			for(int i=0;i<cookies.length;i++) {
				if(cookies[i].getName().equals(name)) {
					result=cookies[i].getValue();
					System.out.println(cookies[i].getName());
					System.out.println(result);
					break;
				}
			}
		}
		return result;
	}
}

 

 

예제 ) 방문 시 조회수 올라가는 효과를 쿠키로 주기

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- import해오기 -->
<%@ page import="java.util.Date"  %>
<%@ page import="common.Util"  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>

<%

//조회수 증가할 때 사용 할 수 있음
String count = Util.getCookie(request.getCookies(), "count");
int intCount = 0;


if(count==null||count.equals("")){//첫 방문일 경우
	//쿠키변수 생성
	response.addCookie(new Cookie("count","1"));	
}else{//재방문을 한 경우
	//계산을 위해 스트링을 int로
	intCount = Integer.parseInt(count)+1;
	//카운터값 변경(항상 String으로 처리해야되니까 다시 String으로 변경)
	response.addCookie(new Cookie("count",Integer.toString(intCount)));
}


%>

방문 횟수 : <%= intCount %>

</body>
</html>

 

예제 ) 방문 시 올라가는 조회수 효과를 이미지로 주기 + 조회수 조작 금지

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- import해오기 -->
<%@ page import="java.util.Date"  %>
<%@ page import="common.Util"  %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src=../include/jquery-3.6.0.min.js></script>
</head>
<body>

<%

//조회수 증가할 때 사용 할 수 있음
String count = Util.getCookie(request.getCookies(), "count");
int intCount = 0;

//조작을 못하도록 방문 시간 저장
Date date = new Date();//날짜 객체 생성
long now_time = date.getTime();//현재시각(1970년 1월1일~현재까지의 초)

//쿠키변수
String visitTime = Util.getCookie(request.getCookies(), "visit_time");
out.println(visitTime+"<br>");//리턴받은 방문시각값을 출력
out.println(visitTime.getClass().getSimpleName()+"<br>");//visitTime의 데이터타입을 확인해봄

long visit_time=0;//String 타입으로 return받은 방문시각을 계산할 수 있는 변수로 준비

//visitTime(방문시각)이 null이 아니고 + 빈 문자열이 아니라면(값이 있다면)
if(visitTime != null && !visitTime.equals("")){
	visit_time = Long.parseLong(visitTime);
	//계산을 위해 String을 Long타입으로 변환처리해준다.
}

out.println("현재시각 : " + now_time + "<br>");
out.println("방문시각 : " + visit_time + "<br>");


if(count==null||count.equals("")){//첫 방문일 경우
	//쿠키변수 생성
	response.addCookie(new Cookie("count","1"));
	//첫 방문 시각 저장
	response.addCookie(new Cookie("visit_time",Long.toString(now_time)));
}else{//재방문을 한 경우
	//방문시간 변경
	long period = now_time - visit_time;//방문시간 = 현재시각 - 이전방문시각
	
	//계산을 위해 스트링을 int로
	intCount = Integer.parseInt(count)+1;
	//조회수 방지를 위한 조건 설정
	if(period > 3*1000){
		//24시간 : 24*60*60*1000 :(하루에 한번만 카운팅)
		//일정시간(3초) 경과하면 카운터 수정
		//카운터값 변경(항상 String으로 처리해야되니까 다시 String으로 변경)
		response.addCookie(new Cookie("count",Integer.toString(intCount)));
		//방문시간 업데이터
		response.addCookie(new Cookie("visit_time",Long.toString(now_time)));
	}
	
}

//Integer.toString(숫자) : 숫자를 문자열로
String counter = Integer.toString(intCount);

//문자열.charAt(인덱스번호) : 해당 문자열의 인덱스 n번째 문자 리턴
out.println("첫번째(인덱스 0) 숫자 : " + counter.charAt(0));
String img = "<img src='../images/"+ counter.charAt(0) +".gif'>";
out.println(img);
out.println("<br>");


for(int i=0;i<counter.length();i++){
	String img3 ="<img src='../images/"+ counter.charAt(i) +".gif'>";
	out.println(img3);
}

%>

<%-- 방문 횟수 : <%= intCount %> --%>


</body>
</html>

 

 

 


세션

1) 세션 생성 및 수정

session.setAttribute("세션변수명",세션값)

세션값에는 모든 Type(object)을 저장할 수 있다.

 

2) 세션 읽기

session.getAttribute("세션변수명")

 

3) 세션의 유효시간 설정

1. 코드에 직접 설정 : session.setMaxInactiveInterval(초);

2. web.xml에 설정하는 방법(분 단위) 기본 30분

<session-config>

  <session-timeout>30</session-timeout>

</session-config>

예) 은행의 경우 고객이 5~10분 정도 반응이 없다면 세션 유효시간을 5분으로 처리해서 자동으로 로그아웃되게끔 처리

 

4) 세션 삭제

개별 삭제 : session.removeAttribute("세션 변수명");

전체 삭제 : session.invalidate();