[Servlet] 세션 트래킹 - 쿠키

Bam·2024년 5월 10일
0

Spring

목록 보기
26/48
post-thumbnail

쿠키

예전에 쿠키와 세션에 대해 다룬 포스트가 있습니다. 따라서 여기에서는 필요한 핵심적인 내용만 간단히 설명해놓고 지나가겠습니다.

쿠키(Cookie)는 웹 페이지에서 발생하는 정보들을 담아 클라이언트측에 저장하는 파일입니다. 쿠키는 정보를 저장해놨다가 웹 페이지에서 요청을 하면 공유해서 사용하게 됩니다.

쿠키의 특징은 다음과 같습니다.

  • 최대 4KB의 작은 크기를 갖는다.
  • 쿠키는 클라이언트측에 저장된다.
  • 이름, 값, 속성(만료일, 도메인, 플래그 등)으로 구성된다.
  • 보안에 취약하다.
  • 브라우저에 쿠키 정보가 있다면 HTTP 요청 헤더에 담아서 전송된다.
  • 하나의 도메인에서 하나의 쿠키가 생성된다.

중요한 것은 보안에 취약하다는 점인데요. 클라이언트 측에 저장되기 때문에 외부에서 접근하기 쉽고 보안성이 낮아지게 됩니다. 그래서 쿠키는 주로 보안성이 요구되지 않는 정보에 대해서 사용됩니다.

즉, 우리가 계속 만들었던 로그인 예제에서 쿠키를 사용한다는 것은 아주 부적절한 예제라고 할 수 있습니다.

쿠키는 Persistence Cookie, Session Cookie 두 종류로 나뉘어집니다.

Persistence Cookie는 다음과 같은 특징이 있습니다.

  • 파일로 클라이언트의 PC에 저장된다.
  • 쿠키를 직접 삭제하거나 만료일이 지난 경우 삭제된다.
  • 최초 접속 시 서버로 전송된다.
  • 로그인 유무, 24시간 내로 팝업을 다시 열지 않음 등과 같은 곳에 사용

Session Cookie는 다음과 같은 특징이 있습니다.

  • 브라우저 메모리에 저장된다.
  • 브라우저 종료시 삭제된다.
  • 최초 접속 시 서버로 전송되지 않는다.
  • 사이트 접속 시 Session 인증 정보를 유지하는 경우 사용
  • 주로 세션과 함께 사용

클라이언트 PC에 저장되는 Persistence Cookie는 구글 크롬 기준으로 다음 경로에서 찾을 수 있습니다.
C:\Users\사용자명\AppData\Local\Google\Chrome\User Data\Default\Cache\Cache_Data

쿠키 동작 과정

웹 페이지에서 쿠키의 동작 과정은 다음과 같습니다.

1. 먼저 웹 페이지에 접속합니다.
2. 서버는 쿠키를 생성합니다.
3. 서버는 생성한 쿠키를 클라이언트로 전송합니다.

1. 서버는 클라이언트에게 쿠키 전송을 요청합니다. 그리고 클라이언트는 쿠키를 서버로 전송합니다.
2. 서버는 전달받은 쿠키를 이용해서 요청받은 작업들을 수행하게 됩니다.

요청 과정에서 쿠키가 없다면 최초 접속으로 인지하게 됩니다.


서블릿에서 쿠키 사용하기

그러면 이제 서블릿을 사용해서 쿠키를 생성하고 쿠키를 전달해 세션 트래킹(정보 공유)를 해보겠습니다.

쿠키를 사용하기 위해서는 jakarta.servlet.http.Cookie 클래스를 사용합니다. Cookie 클래스에서는 쿠키에 정보를 담거나 가져올 수 있는 메소드들을 제공하고 있습니다.

Cookie 클래스에서 제공하고있는 주요 메소드들은 다음과 같습니다.

메소드설명
setComment(String comment), getComment()쿠키에 대한 설명을 설정/취득합니다.
setDomain(String domain), getDomain()쿠키의 유효한 도메인을 설정/취득합니다.
setMaxAge(int age), getAge()쿠키의 만료일을 설정/취득합니다. (단위는 초)
setValue(String value), getValue()쿠키의 값을 설정/취득합니다.
setPath(String path), getPath()쿠키의 디렉터리 정보를 설정/취득합니다.
getName()쿠키의 이름을 취득합니다.

만들어진 쿠키는 HttpServletResponse.addCookie() 메소드를 호출해 클라이언트에 쿠키를 보내고 저장하게 만들며, HttpServletRequest.getCookie()를 호출해 쿠키를 서버로 전달받을 수 있도록 작동시킵니다.

쿠키 사용하기

그러면 이제 실제로 서블릿에서 쿠키를 만들고 전달받아보겠습니다.

먼저 쿠키를 생성하도록하는 setCookieServlet.java를 작성합니다.

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

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

@WebServlet("/setCookie")
public class setCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        
        //myCookie 라는 이름으로 문자열이 담긴 쿠키를 생성
        Cookie cookie = new Cookie(
                "myCookie",
                URLEncoder.encode("서블릿으로 생성한 쿠키", "utf-8")
        );
        cookie.setMaxAge(3600);	//쿠키 만료일 설정 (3600초 = 1시간)
        resp.addCookie(cookie);	//생성된 쿠키를 브라우저에 전송
        out.println("쿠키를 저장했습니다.");
    }
}

실습용으로 생성된 쿠키는 사실상 쓰레기 데이터이기 때문에 알아서 삭제되도록 만료일을 설정해주었습니다.

다음으로는 생성한 쿠키를 받아 쿠키의 내용을 브라우저에 표시할 getCookieServlet.java를 작성합니다.

package com.example.helloservlet.sessiontracking;

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;

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

@WebServlet("/getCookie")
public class getCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        
        //브라우저에게 쿠키 정보를 요청해서 쿠키 배열로 가져옴
        Cookie[] cookies = req.getCookies();
        
        //제어구조에 대한 설명은 아래의 인용문 참조
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("myCookie")) {
                out.println("<h2>가져온 쿠키: " + cookie.getName() + "</h2>");
                out.println("쿠키 값: " +
                        URLDecoder.decode(cookie.getValue(), "UTF-8")
                );
            }
        }
    }
}

for 문if 문의 제어구조를 넣은 이유는 그동안 사용했던 브라우저나 IDE의 설정 등에 의해 다른 쿠키가 삽입되는 경우도 있습니다. 그렇기 때문에 우리가 만든 쿠키만을 확인하기 위해 가져온 쿠키 배열에서 if문을 통해 우리가 실습한 쿠키만 출력하도록 만들어준 것 입니다.

서버를 실행해서 /setCookie로 먼저 쿠키를 생성하고 저장한 뒤 /getCookie로 쿠키를 가져와봅시다.
쿠키에 정보 설정, 저장, 가져오기가 모두 잘 됐죠?

세션 쿠키 사용하기

위 실습에서 사용한 쿠키는 만료일이 지정된 Persistence 쿠키였습니다. 이를 브라우저가 종료되면 자동으로 삭제되는 세션 쿠키로 만들기 위해서는 쿠키의 만료일을 설정하는 setMaxAge()에 전달하는 값을 -1과 같은 음수로 전달하면 됩니다.

@WebServlet("/setCookie")
public class setCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        
        Cookie cookie = new Cookie(
                "myCookie",
                URLEncoder.encode("서블릿으로 생성한 쿠키", "utf-8")
        );
        cookie.setMaxAge(-1);	//음수를 전달하면 브라우저가 종료될 때 쿠키가 삭제
        resp.addCookie(cookie);
        out.println("쿠키를 저장했습니다.");
    }
}

0개의 댓글