쿠키(Cookie)와 세션(Session)

이재민·2023년 8월 20일
2

웹 기본지식

목록 보기
3/5

📖쿠키와 세션을 사용하는 이유는?

HTTP 프로토콜의 특징 이자 약점을 보완 하기 위해서 쿠키 또는 세션을 사용한다.


📖HTTP의 특징

쿠키와 세션을 이해하기위해 HTTP의 특징을 간다한게 짚고 넘어 가려고 한다.
HTTP 프로토콜 환경은 "connectionless, stateless"한 특성을 가지기 때문에 서버는 클라이언트가 누구인지 매번 확인해야합니다. 이 특성을 보완하기 위해서 쿠키세션을 사용하게 된다.

Connectionless 프로토콜 (비연결 지향)
클라이언트가 서버에 요청(Request)을 했을 때, 그 요청에 맞는 응답(Response)을 보낸 후 연결을 끊는 처리방식이다.
Stateless 프로토콜
연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는 특성이 있다.


쿠키란?

  • 쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일이다.
  • 사용자가 어떠한 웹 사이트를 방문할 경우, 쿠키는 클라이언트의 상태 정보를 로컬에 참조하거나 재사용할 수 있다.
  • 쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조한다.

쿠키 특징

  • 이름, 값, 만료일(저장기간), 경로, 도메인 으로 구성되어 있다.
  • 클라이언트에 300개의 쿠키를 저장할 수 있다.
  • 하나의 도메인 당 20개의 쿠키를 가질 수 있다.
  • 하나의 쿠키는 4KB(=4096byte)까지 저장 가능하다.

쿠키의 동작 방식(순서)

  1. 클라이언트가 페이지를 요청 (사용자가 웹사이트에 접근)
  2. 웹 서버에서 쿠키를 생성
  3. 생성한 쿠키에 정보를 담아 HTTP 화면을 돌려줄 때, HTTP 헤더에 쿠키를 포함 시켜 응답
  4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관
  5. 다시 서버에서 같은 요청을할 때 요청과 함께 쿠키를 전송
  6. 동일 사이트 재방문 시 클라이언트의 PC에 해당 쿠키가 있는 경우, 요청 페이지와 함께 쿠키를 전송

쿠키 사용의 예

  • 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
  • 쇼핑몰의 장바구니 기능
  • 팝업창을 통해 "오늘 이 창을 다시 보지 않기" 체크

*쿠키사용 화면 첨부

package pack;

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

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("/CookieTest")
public class CookieTest extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        // 쿠키가 없는 경우에만 로그인 화면 출력
        String id = null;
        String pwd = null;
        try {
			Cookie[] cookies = request.getCookies(); // 클라이언트 쿠기를 모두 읽음
			for(int i=0; i < cookies.length; i++) {
				String name = cookies[i].getName();
				System.out.println("읽은 쿠키 name : " + name);
				if(name.equals("id")) {
					id = URLDecoder.decode(cookies[i].getValue(), "utf-8");
				}
				if(name.equals("pwd")) {
					pwd = URLDecoder.decode(cookies[i].getValue(), "utf-8");
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
        
        if(id != null && pwd != null) {
        	out.println(id+ "님 쿠기를 통해 로그인 상태입니다");
        	out.println("</body></html>");
        	out.close();
        	return;
        }
        
        out.println("*로그인*");
        out.println("<form method='post'>");
        out.println("i d : <input type='text' name='id'><br/>");
        out.println("pwd : <input type='password' name='pwd'><br/>");
        out.println("<input type='submit' value='로그인'>");
        out.println("</form>");
        out.println("</body></html>");
        out.close();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        String id = request.getParameter("id");
        String pwd = request.getParameter("pwd");
        System.out.println(id + " " + pwd);

        if (id.equals("aa") && pwd.equals("11")) {
            try {
                // 로그인에 성공하면 쿠키 작성
                id = URLEncoder.encode(id, "utf-8");
                Cookie idCookie = new Cookie("id", id); // javax의 쿠키임
                idCookie.setMaxAge(60 * 60 * 24 * 365);

                pwd = URLEncoder.encode(pwd, "utf-8"); // 이 부분 수정
                Cookie pwdCookie = new Cookie("pwd", pwd); // javax의 쿠키임
                pwdCookie.setMaxAge(60 * 60 * 24 * 365);

                response.addCookie(idCookie); // 클라이언트 컴에 저장
                response.addCookie(pwdCookie);

                out.println("로그인 성공 - 쿠키가 설정됨");
            } catch (Exception e) {
                out.println("쿠키 작성 실패");
                System.out.println("쿠키 작성 실패: " + e);
            }
        } else {
            out.println("로그인 실패");
        }
    }
}

📖세션 ( Session )

  • 세션은 쿠키를 기반하고 있지만, 세션은 서버 측에서 클라이언트의 상태를 관리하는 메커니즘이다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
    (접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정이 가능)
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지한다.

세션 특징

  • 각 클라이언트에게 고유 ID를 부여 한다. (Session ID)
  • 세션 ID로 클라이언트를 구분해서 클라이언트의 요구에 맞는 서비스를 제공 한다.
  • 보안 면에서 쿠키보다 우수 하다.
    (브라우저를 닫거나, 서버에서 세션을 삭제했을 때만 삭제가 되기 때문)
  • 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.

세션의 동작 방식(순서)

  1. 사용자가 웹 사이트에 접속하면, 서버에서 고유한 세션 ID를 생성
  2. 서버는 세션 ID를 사용자의 브라우저에 쿠키로 전송
  3. 클라리언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청
  4. 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져와서 사용
  5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답

세션 사용의 예

  • 화면을 이동해도 로그인이 풀리지 않고 로그아웃하기 전까지 유지
  • 로그인 같이 보안상 중요한 작업을 수행할 때 사용
package pack;

import java.io.IOException;
import java.io.PrintWriter;

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

/**
 * Servlet implementation class SessionTest
 */
@WebServlet("/SessionTest")
public class SessionTest extends HttpServlet {
	private static final long serialVersionUID = 1L;
	//세션은 방문자의 요청에 따른 정보를 방문자 메모리에 저장하는 것이 아닌 웹 서버가 세션 아이디 파일을 만들어
	//서비스가 돌아가고 있는 서버에 저장을 하는 것을 말한다.
       
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession(true); // 현재 접속한 사용자의 세션이 있으면 읽고 없으면 생성 o
		// HttpSession session = request.getSession(false); // 현재 접속한 사용자의 세션이 있으면 읽고 없으면 생성 x
		
		session.setMaxInactiveInterval(5); // 5초 간 세션 유효 (기본 값은 30분)
		
		if(session != null) {
			session.setAttribute("name", "홍길동");
		}
		
		response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("session id :" + session.getId());
        out.println("<br>사용자명 :" + session.getAttribute("name"));
        out.println("</body></html>");
        out.close();
	}


}

쿠키와 세션의 차이

❗ 쿠키와 세션의 저장위치, 보안, 속도, 라이프 사이클 차이를 알고있어야 한다.

  • 쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷하다. 세션도 결국 쿠키를 사용하기 때문이다
  • 가장 큰 차이점은 사용자의 정보가 저장되는 위치이다.
    (쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용)
  • 보안 면에서 세션이 더 우수하며, 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약 하다.
  • 라이프 사이클은 쿠키도 만료기간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 정보가 유지될 수 있다. 또한 만료기간을 따로 지정해 쿠키를 삭제할 때까지 유지할 수도 있다. 반면에 세션도 만료기간을 정할 수 있지만, 브라우저가 종료되면 만료기간에 상관없이 삭제된다.
  • 속도, 쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가진다.
종류쿠키(Cookie)세션(Session)
저장 위치클라이언트(사용자 pc)웹 서버
저장 형식textObject
만료 시점브라우저가 종료되어도,
종료시점이 지나지 않으면
삭제되지않음
브라우저 종료시 삭제
사용하는 자원(리소스)클라이언트 리소스웹서버 리소스
용량 제한총 300개
도맨인당 20개
쿠키하나당 4kb
서버가 허용하는 한 제한없음
속도세션보다 빠르다쿠키 보다 느리다
보안세션보다 안좋다쿠키보다 좋다
profile
안녕하세요

0개의 댓글