본문 바로가기

Computer Science/네트워크

[네트워크] 쿠키와 세션이란? + 스프링 MVC에서 사용법

1. 쿠키 (Cookie)

쿠키란?

쿠키는 사용자의 브라우저에 저장되는 데이터입니다. 웹사이트는 쿠키를 사용해 사용자가 이전에 방문했을 때의 정보를 유지할 수 있습니다.

장단점

  1. 장점
    • 상태 유지: 사용자가 웹 사이트를 다시 방문할 때 이전 상태를 유지할 수 있습니다.
    • 간편한 구현: 브라우저에서 쿠키를 관리하기 때문에 서버 측에서 쿠키를 지정하기만 하면 되어 간단합니다.
    • 클라이언트에 저장: 서버 자원을 절약할 수 있습니다.
  2. 단점
    • 보안: 쿠키는 클라이언트 측에 저장되므로 민감한 정보를 암호화하지 않으면 보안 취약점이 생길 수 있습니다.
    • 저장 용량 제한: 각 쿠키의 크기는 4KB로 제한되며, 브라우저 당 저장 가능한 쿠키 수에도 제한이 있습니다.
    • 브라우저 종속적: 브라우저 설정에 따라 쿠키 사용이 제한될 수 있습니다.

사용방법

서버에서 브라우저로 응답하는 HTTP 메시지 헤더에 Set-Cookie를 지정하면, 브라우저는 다음 요청부터 자동으로 HTTP 메시지 헤더에 쿠키를 포함시킵니다.

 

Spring MVC에서 쿠키를 지정하려면 HttpServletResponse의 addCookie()를 호출하면 됩니다.

@GetMapping("/set-cookie")
public String setCookie(HttpServletResponse response) {
    Cookie cookie = new Cookie("username", "JohnDoe");
    cookie.setMaxAge(3600);
    cookie.setHttpOnly(true);
    cookie.setPath("/");
    response.addCookie(cookie); // 서버 응답 Response에 쿠키를 추가한다.
    return "Cookie set";
}

/v0/set-cookie Response Headers 주목
브라우저 스토리지 내 쿠키

 

클라이언트가 요청 헤더에 담은 쿠키를 읽으려면 HttpServletRequest의 getCookies()를 호출하면 됩니다.

@GetMapping("/get-cookie")
public String getCookie(HttpServletRequest request) {
    Cookie[] cookies = request.getCookies(); // 클라이언트 요청 Request에서 쿠키를 읽는다.
    if(cookies != null)
        for(Cookie cookie : cookies)
            if(cookie.getName().equals("username"))
                return "Username: " + cookie.getValue();
    return "No cookie found";
}

/v0/get-cookie Request Headers 주목

 

2. 세션 (Session)

세션이란?

세션은 서버 측에서 관리되는 사용자의 데이터입니다. 사용자가 웹 사이트에 접속하면 서버는 고유한 세션 ID를 생성하고, 이를 통해 해당 사용자의 데이터를 관리합니다. 세션 ID는 보통 쿠키에 담겨 클라이언트에 전달됩니다.

장단점

  1. 장점
    • 상태 유지: 서버는 사용자 상태 저장을 통해 사용자가 웹 사이트를 다시 방문할 때 데이터를 유지할 수 있습니다.
    • 보안: 예측 불가능한 임의의 세션 ID를 주고 받기 때문에, 세션 ID 자체로부터 정보 유출이 없습니다. 중요한 정보는 서버에 저장되므로, 클라이언트는 민감 정보에 접근할 수 없습니다.
  2. 단점
    • 다음과 같은 문제들이 발생할 수 있습니다.
      • 세션 하이재킹: 공격자가 사용자의 세션 ID를 도용해 사용자로 가장할 수 있음.
      • 세션 고정: 공격자가 특정 세션 ID를 고정해 해당 세션 ID를 계속해서 사용할 수 있음.
      • 세션 만료: 사용자가 작업 중 세션이 만료되면 불편을 겪을 수 있음.
      • 서버 자원소모: 많은 사용자가 접속하면 서버 메모리 사용량이 증가할 수 있음.
      • 확장성 문제: 서버가 여러 대인 경우 세션을 특정 서버에만 저장하면 로드 밸런싱, 확장이 어려워 질 수 있음.
      • CSRF: 공격자가 사용자의 세션을 이용해 사용자 몰래 악의적인 요청을 전송할 수 있음.

사용방법

서버에서 브라우저로 응답하는 HTTP 메시지 헤더에 Set-Cookie로 세션 아이디를 담아 응답합니다.

 

Spring MVC에서 세션을 지정하려면 HttpSession 또는 HttpServletRequest의 getSession()을 호출하면 됩니다.

@GetMapping("/set-session")
public String setSession(HttpSession session) {
    session.setAttribute("username", "JohnDoe");
    return "Session set";
}

@GetMapping("/set-session")
public String setSession(HttpServletRequest request) {
    HttpSession session = request.getSession();
    session.setAttribute("username", "JohnDoe");
    return "Session set";
}

/v2/set-session Response Headers 주목 (JSESSIONID 쿠키)

 

세션을 읽을 때도 마찬가지로 HttpSession을 컨트롤러 핸들러 메서드의 매개변수로 주입 받거나, HttpServletRequest의 getSession()을 호출하면 됩니다.

@GetMapping("/get-session")
public String getSession(HttpSession session) {
    String username = (String) session.getAttribute("username");
    if(username != null)
        return "Username: " + username;
    return "No session found";
}

@GetMapping("/get-session")
public String getSession(HttpServletRequest request) {
    HttpSession session = request.getSession(false); 
    String username = (String) session.getAttribute("username");
    if(username != null)
        return "Username: " + username;
    return "No session found";
}

/v2/get-session Request Headers 주목 (JSESSIONID 쿠키)

 

HttpSession과 HttpServletRequest의 getSession() 또는 getSession(true)는 JSESSIONID에 해당하는 세션이 없을 경우, 새롭게 세션을 생성해 반환합니다.

반면 HttpServletRequest의 getSession(false)는 JSESSIONID에 해당하는 세션이 없을 경우, null을 반환합니다.

 

이렇듯 HttpServletRequest를 사용하면 HttpSession 보다 좀 더 세밀한 세션 관리를 할 수 있습니다.