Day 4-2
13. Cookie
13.1. Cookie란?
- 클라이언트의 연결을 일정 시간동안 유지시켜주는 수단
- 클라이언트 브라우저에서 쿠키를 만들고, 클라이언트 브라우저에서 저장이 된다
- 쿠키를 먹다가 부스러기를 흘리듯이, 브라우저 상에 흔적을 남기는게 쿠키이다. 즉 브라우저 상에 기존 연결정보가 연결되어있었던 흔적이 남는 것.
- http 프로토콜의 특징
- 브라우저에서 서버로 request, 서버에서 브라우저로 response. 이때 http 프로토콜은 response 이후 클라이언트와 서버의 연결을 바로 해제해버린다.
- 왜? 클라이언트가 수백, 수천개가 될 텐데, 연결 정보를 다 저장하고 있으면 과부하가 올 수도 있기 때문이다. 즉 리소스를 낭비하지 않기 위하여 바로 연결을 해제한다. => 장바구니에 담은 데이터가 장바구니로 가니 다 사라져있는 등의 상황이 발생. 이를 해결하기 위해 특정 연결 정보를 저장해두는
쿠키
를 사용한다.
13.2. Cookie 구현
- coockie가 null이면 cookie를 생성, 그렇지않으면 cookie를 재활용한다.
- 쿠키는 사용자쪽에 정보가 있으므로 request해서 받아온다.
- 쿠키는 약간 보안에 취약할 수 있다. 정보가 사용자측에 저장되어 있으므로, 중요하거나 크리티컬한 이슈가 발생할 수 있는 정보는 쿠키에 저장하지 말기.
login.jsp
<%@ 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>
</head>
<body>
<%
Cookie[] cookies = request.getCookies(); //클라이언트에게 쿠키 정보 요청하여 받는다 (배열 형태)
System.out.println("cookies : " + cookies);
// 쿠키가 없는 상태 = 할당된 Age 모두 소모 || 첫 로그인
if(cookies != null) {
for(Cookie c : cookies) {
if(c.getName().equals("memberId")) {
//쿠키가 있으면 재로그인 할 필요가 없으므로 리다이렉트
response.sendRedirect("loginOk.jsp");
}
}
}
%>
// 쿠키가 없어서 로그인해야하는 상황
<form action="loginCon" method="post">
ID : <input type="text" name="mID">
PW : <input type="password" name="mPW">
<input type="submit" value="login">
</form>
</body>
</html>
loginOk.jsp (쿠키가 있는 상황)
<%@ 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>
</head>
<body>
<%
Cookie[] cookies = request.getCookies();
for(Cookie c : cookies) {
out.print("name : " + c.getName() + "<br>");
out.print("value : " + c.getValue() + "<br>");
out.print("--------------------------------");
}
%>
</body>
</html>
- 쿠키를 받아와서, 모든 쿠키의 이름과 값을 찍어본다.
name : JSESSIONID value : 02D5C4FF39516E6B536652DB4BB8ED11
요렇게 뜬건 서블릿에서 자동으로 넣어준 놈이라고 한다.
loginCon.jsp (쿠키가 없는 상황)
- 쿠키가 없어서
login.jsp
에서 로그인 정보를 받아와(form) 파라미터들을 띄워, 쿠키에 저장을 해준다. (“memberId”라는 이름을 가진 쿠키가 있는지 다시 한 번 확인하는 이유를 모르겠어서, 현재 강사님께 질문해두었다.)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String mId = request.getParameter("mID");
String mPw = request.getParameter("mPW");
out.print("mId : " + mId);
out.print("mPw : " + mPw);
Cookie[] cookies = request.getCookies();
Cookie cookie = null;
for(Cookie c : cookies) {
System.out.println("c.getName() : " + c.getName() + ", c.getValue() : " + c.getValue());
if(c.getName().equals("memberId")) {
cookie = c;
}
}
if(cookie==null) {
System.out.println("cookie is null");
cookie = new Cookie("memberId", mId);
}
response.addCookie(cookie);
cookie.setMaxAge(60*60);
response.sendRedirect("loginOk.jsp");
}
14. Session
14.1. Session이란?
- 세션은 웹 컨테이너(서버단)에서 만들고 이를 통해 클라이언트와 서버가 연결을 유지시켜준다. 저장도 서버에서 저장됨.
- 쿠키와 세션 모두 일정 시간이 지나면 연결이 끊긴다.
14.2. Session 구현
- LoginCon.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String mId = request.getParameter("mId");
String mPw = request.getParameter("mPw");
out.print("mId : " + mId);
out.print("mPw : " + mPw);
HttpSession session = request.getSession();
session.setAttribute("memberId", mId);
response.sendRedirect("loginOk.jsp");
}
- HttpSession 클래스로 세션을 받아와, 로그인 페이지에서 받은 mId로 Attribute를 설정해주고 있다. 이후 리다이렉트.
- 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질 수록 서버 메모리를 많이 차지하게 된다. (동접자 수가 많은 웹사이트의 경우엔 서버에 과부하를 주게 된다.)
- 세션은 사용자의 수만큼 서버 메모리를 차지하기 때문에, 이런 문제를 보완한 토큰 기반의 인증방식을 사용한다.
쿠키와 세션 라이프사이클 차이
쿠키
- 클라이언트가 페이지를 요청
- 서버에서 쿠키를 생성
HTTP 헤더
에 쿠키를 포함시켜 응답- 브라우저가 종료되어도 쿠키 만료 기간이 있다면
클라이언트
에서 보관 - 같은 요청을 할 경우
HTTP 헤더
에 쿠키를 함께 보냄 - 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때, 쿠키를 업데이트하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답
- 사용 예시 : 쇼핑몰 장바구니, 자동로그인, 오늘은 더이상 이 창을 보지 않음 체크
세션
- 클라이언트가 서버에 접속 시 서버로부터 세션 ID 발금받음
- 클라이언트는 세션 ID에 대해 쿠키를 사용하여 저장
- 클라이언트는 서버에 요청할 때, 이 쿠키의 세션ID를 서버에 전달
- 서버는 세션 ID로 세션에 있는 클라이언트 정보를 가져온다
- 클라이언트 정보를 가지고 서버 요청을 처리 후 클라이언트에게 응답