쿠키, 세션 - Cookie

김회민·2023년 2월 21일
0

Spring

목록 보기
14/25

클라이언트의 Cookie Storage에 Key-Value 형태로 저장되는 자료구조를 뜻한다.

서버에서 클라이언트에게 응답을 줄 때 Set-Cookie Header에 담아서 전달하게 되면, 브라우저는 Cookie Storage에 저장하게 된다.

저장된 쿠키는 클라이언트가 요청을 할 때마다 저장 되어있는 모든 쿠키들(최대 300개)을 Cookie Header에 담아서 보내게 된다.

서버는 요청 헤더에 쿠키가 있다면, 그 쿠키에 접근하여 그에 맞는 처리를 진행할 수 있다.

서버에서 쿠키를 보낼때 만료 시간을 입력할 수 있으며, 만료 시간을 어떻게 지정하냐에 따라 영속 쿠키와 세션 쿠키로 나뉘게 된다.

  • 영속 쿠키: 만료 시간을 입력하면, 브라우저를 종료하더라도 만료 시간 전에는 계속 유지된다.
  • 세션 쿠키: 만료 시간을 입력하지 않으면, 브라우저가 종료될시 쿠키가 삭제된다.
package jakarta.servlet.http;

public class Cookie implements Cloneable, Serializable {
    public Cookie(String name, String value) { ... }

    // 도메인 설정
    public void setDomain(String pattern) { ... }

    // 유효 기간 설정 (s)
    public void setMaxAge(int expiry) { ... }

    // 유효 경로 설정
    public void setPath(String uri) { ... }

    // 보안 여부 설정
    public void setSecure(boolean flag) { ... }

    // 자바스크립트 접근 여부 설정
    public void setHttpOnly(boolean httpOnly) { ... }

    // 값 변경
    public void setValue(String newValue) { ... }

    // 키-값 변경
    public void setAttribute(String name, String value) { ... }
}

Spring에서는 Cookie 클래스를 통해 쿠키를 생성할 수 있도록 지원한다.

메서드 설명

  • setDomain(String pattern)
    • 해당 쿠키의 유효 도메인을 설정한다.
    • 기본값: 데이터를 전송한 서버 도메인
  • setMaxAge(int expiry)
    • 해당 쿠키의 유효 기간을 설정한다. (초)
    • 기본값: -1
  • setPath(String uri)
    • 해당 쿠키의 유효 경로를 설정한다.
    • 기본값: 해당 쿠키를 전송한 서버 경로의 부모 경로
    • 예) /auth/login 에서 쿠키를 전송했다면 /auth 가 전송된다.
  • setSecure(boolean flag)
    • 해당 쿠키의 보안 여부를 설정한다.
    • true로 설정하면 HTTPS 통신에서 전송된다.
    • false로 설정하면 HTTPS 통신에서 전송되지 않는다.
    • 기본값: false
  • setHttpOnly(boolean httpOnly)
    • 해당 쿠키의 자바스크립트 접근 여부를 설정한다.
    • true로 설정하면 자바스크립트에서 접근할 수 없다.
    • 기본값: false
  • setValue(String newValue)
    • 해당 쿠키의 값을 재설정한다.
  • setAttribute(String name, String value)
    • 해당 쿠키의 Key-Value를 재설정한다.

HttpServletResponse.addCookie

Cookie cookie = new Cookie("Cookie Key", "Cookie Value");
response.addCookie(cookie);

HttpServletResponse의 addCookie 메서드를 통해 클라이언트에게 전달할 수 있다.

HttpServletRequest.getCookies

Cookie[] cookies = request.getCookies();
if (cookies != null) {
    Optional<String> cookieValue = Arrays.stream(cookies)
          .filter(cookie -> cookie.getName().equals("memberId"))
          .map(Cookie::getValue)
          .findFirst();
}

쿠키를 가져오기 위해선 위의 과정을 거치면 가져올 수 있는데, 위의 방법은 뭔가 불편하다.

그래서 Spring은 애노테이션을 통해 쿠키를 가져올 수 있도록 지원한다.

@CookieValue

@GetMapping("/cookie")
public String getCookie(
        @CookieValue(
                value = "myCookie",
                required = false
        ) String cookieValue
) {
    log.info("cookieValue: {}", cookieValue);
    return "ok";
}

컨트롤러의 Argument에 @CookieValue 애노테이션을 붙임으로써 특정 쿠키의 값을 가져올 수 있다.

  • name, value
    • 브라우저에선 보낸 쿠키의 Key 이름
    • 따로 입력하지 않으면 해당 변수의 이름(cookieValue)을 찾는다.
  • required
    • 해당 쿠키의 필수 여부를 설정한다.
    • true로 설정했는데 값이 없는 경우, MissingRequestCookieException을 발생시킨다.
    • false로 설정했는데 값이 없는 경우, cookieValue에 null이 입력된다.
    • 기본값: true

Cookie의 문제점

  1. 쿠키는 클라이언트가 임의대로 설정할 수 있다.
  2. SSL를 등록하지 않은 서버의 경우 요청의 값을 암호화없이 그대로 보내기 때문에 탈취당할 위험성이 있다.
  3. 해커가 쿠키를 한 번 훔쳐가면 평생 사용할 수 있다.

문제점의 대안 방안

  1. 쿠키에 민감한 정보를 저장해서는 안된다.
  2. 쿠키의 값을 설정할때 UUID나 특수한 랜덤 함수를 이용해 ID만 전달하고, 서버에서는 ID를 받아 처리하는 방식으로 구현해야 한다.
  3. 쿠키의 만료 시간을 짧게 설정한다.
  4. 해당 쿠키에 이상한 동작이 포착된다면, 서버에서 강제로 쿠키를 제거할 수 있도록 해야 한다.
profile
백엔드 개발자 지망생

0개의 댓글