Spring_18_Cookie

OngTK·2025년 10월 21일

Spring

목록 보기
18/25

🍪 Spring Boot Controller 단 - 쿠키 처리 정리

Spring MVC Controller 단에서 쿠키를 생성, 조회, 삭제하는 방법을 정리함.
주로 로그인 유지(JWT/세션 토큰 저장) 및 사용자 환경 설정(언어, 테마 등)에 사용됨.


1️⃣ 쿠키란?

  • 클라이언트(브라우저)에 작은 데이터 조각을 저장하여 서버 요청 시 함께 전송하는 메커니즘
  • 로그인 상태 유지, 사용자 식별, 설정값 저장 등에 사용
  • 단, 민감한 정보(비밀번호, 개인정보) 는 절대 저장하지 않음 (토큰 등만 저장)

2️⃣ 쿠키 생성 및 내려주기

(1) javax.servlet.http.Cookie 사용 예시

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest req, HttpServletResponse res) {

    // 사용자 인증 완료 후 JWT 또는 세션 토큰 발급
    String jwt = tokenService.createToken(req.getEmail());

    // 쿠키 객체 생성
    Cookie cookie = new Cookie("AUTH", jwt);

    // 보안 옵션 설정
    cookie.setHttpOnly(true);       // JS 접근 차단 (XSS 완화)
    cookie.setSecure(true);         // HTTPS에서만 전송
    cookie.setPath("/");            // 전체 경로에서 접근 가능
    cookie.setMaxAge(60 * 60 * 24); // 1일(초 단위)

    // 응답에 쿠키 추가
    res.addCookie(cookie);

    return ResponseEntity.ok("[로그인 성공] 쿠키 저장 완료");
}

(2) ResponseCookie (Spring Web) 사용 — 추천 방식

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest req) {
    String jwt = tokenService.createToken(req.getEmail());

    ResponseCookie cookie = ResponseCookie.from("AUTH", jwt)
            .httpOnly(true)
            .secure(true)              // HTTPS 권장
            .sameSite("Lax")           // 'Strict', 'Lax', 'None' 선택 가능
            .path("/")
            .maxAge(Duration.ofDays(1))
            .build();

    return ResponseEntity.ok()
            .header(HttpHeaders.SET_COOKIE, cookie.toString())
            .body("[로그인 성공] ResponseCookie 방식으로 쿠키 저장");
}

SameSite 옵션 요약

옵션설명
Strict다른 사이트 요청 시 절대 쿠키 전송 안함 (CSRF 방지 강력)
Lax대부분의 안전한 GET 요청에 한해 쿠키 전송 (기본 권장)
None크로스 도메인 허용 (Secure=true 필수) — SPA 환경에서 사용

3️⃣ 쿠키 읽기

(1) @CookieValue 어노테이션 사용

@GetMapping("/me")
public ResponseEntity<?> me(@CookieValue(name = "AUTH", required = false) String token) {
    if (token == null) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("로그인 필요");
    return ResponseEntity.ok("[인증 성공] Token: " + token);
}

(2) HttpServletRequest 로 쿠키 직접 파싱

@GetMapping("/me2")
public ResponseEntity<?> me2(HttpServletRequest req) {
    Cookie[] cookies = req.getCookies();
    if (cookies == null) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("쿠키 없음");

    String token = Arrays.stream(cookies)
            .filter(c -> "AUTH".equals(c.getName()))
            .map(Cookie::getValue)
            .findFirst()
            .orElse(null);

    if (token == null) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("인증 실패");
    return ResponseEntity.ok("[인증 성공] Token: " + token);
}

4️⃣ 쿠키 삭제 (무효화)

@PostMapping("/logout")
public ResponseEntity<?> logout() {

    // 동일한 속성으로 설정한 쿠키를 덮어쓰기 + 만료 시간 0
    ResponseCookie expired = ResponseCookie.from("AUTH", "")
            .httpOnly(true)
            .secure(true)
            .sameSite("Lax")
            .path("/")
            .maxAge(0)  // 즉시 만료
            .build();

    return ResponseEntity.ok()
            .header(HttpHeaders.SET_COOKIE, expired.toString())
            .body("[로그아웃 완료] 쿠키 삭제됨");
}

⚠️ 삭제 시 반드시 같은 이름·Path·SameSite 속성을 지정해야 정확히 덮어쓰기 됨.


5️⃣ 쿠키 관련 보안 체크리스트

옵션설명
HttpOnly자바스크립트 접근 차단 (XSS 방지)
SecureHTTPS 환경에서만 전송
SameSite외부 사이트 요청 시 쿠키 전송 여부 제어
Max-Age / Expires쿠키의 만료시간 설정
평문 저장 금지비밀번호나 개인정보는 절대 저장하지 않음
암호화JWT 또는 세션ID 등 식별 토큰만 저장

6️⃣ 실무 팁

  • JWT + 쿠키 조합 시: HttpOnly + Secure + SameSite=Lax 권장
  • SPA 프런트(React/Vue 등)와 연동 시 CORS와 CSRF 정책을 반드시 함께 고려
  • 세션 쿠키는 Max-Age 없이 설정 (브라우저 종료 시 자동 삭제)
  • SameSite=None 사용 시 반드시 HTTPS(secure=true)로 설정

✅ 핵심 요약

항목내용
쿠키 생성Cookie 또는 ResponseCookie 사용
보안 설정HttpOnly / Secure / SameSite 설정 필수
조회 방식@CookieValue, HttpServletRequest.getCookies()
삭제 방식동일한 Path와 이름으로 MaxAge=0 쿠키 반환
주의점평문 데이터 저장 금지, HTTPS 환경 필수
profile
2025.05.~K디지털_풀스택 수업 수강중

0개의 댓글