[Spring] 스프링의 로그인 구현 방식 비교

Neo-Renaissance·2025년 1월 17일

1. 쿠키 로그인

쿠키 로그인은 사용자의 로그인 정보를 클라이언트의 브라우저에 저장하는 방식입니다. 클라이언트가 서버에 요청을 보낼 때마다 저장된 쿠키가 함께 전송됩니다. 이를 통해 사용자의 인증 상태를 유지할 수 있습니다.

  • 특징

    • 구성 요소: 쿠키는 키-값 쌍으로 구성되어 있으며, 사용자 식별 정보를 포함합니다.

    • 저장 위치: 클라이언트 브라우저에 저장됩니다.

    • 보안 문제:

      • 쿠키는 클라이언트 측에 저장되므로 탈취될 위험이 있습니다.

      • XSS(Cross-Site Scripting) 공격에 취약할 수 있습니다.

      • 민감한 정보를 암호화하지 않으면 정보 유출 가능성이 높습니다.

예시 코드

// 쿠키 생성 및 설정
Cookie cookie = new Cookie("authToken", "userTokenValue");
cookie.setHttpOnly(true); // XSS 방지
cookie.setMaxAge(7 * 24 * 60 * 60); // 7일간 유효
response.addCookie(cookie);

// 쿠키 읽기
Cookie[] cookies = request.getCookies();
if (cookies != null) {
    for (Cookie c : cookies) {
        if ("authToken".equals(c.getName())) {
            String token = c.getValue();
            // 토큰 처리 로직
        }
    }
}
  • 장점

    • 간단한 구현과 관리.

    • 서버의 메모리나 저장소를 사용하지 않음.

  • 단점

    • 보안에 취약하며, 쿠키 크기 제한(일반적으로 4KB)이 있습니다.

    • 클라이언트 측에서 쿠키 삭제 시 인증 상태가 무효화됩니다.

2. 세션 로그인

세션 로그인은 사용자 인증 정보를 서버에 저장하고, 클라이언트는 세션 ID만 쿠키에 저장하여 전송하는 방식입니다. 서버는 클라이언트로부터 받은 세션 ID를 기준으로 인증 상태를 확인합니다.

  • 특징

    • 구성 요소: 세션 ID는 서버에서 생성되며 클라이언트의 요청마다 쿠키를 통해 서버로 전달됩니다.

    • 저장 위치: 서버 메모리나 데이터베이스.

    • 보안:

      • 쿠키에 민감한 정보를 저장하지 않으므로 비교적 안전합니다.

      • 세션 탈취(Session Hijacking) 공격에 주의해야 합니다.

예시코드

// 세션 생성
HttpSession session = request.getSession();
session.setAttribute("user", "loggedInUser");

// 세션 읽기
String user = (String) session.getAttribute("user");
if (user != null) {
    // 인증된 사용자 처리
}

// 세션 무효화
session.invalidate();
  • 장점

    • 민감한 정보를 클라이언트에 저장하지 않아 보안성이 높음.

    • 클라이언트 측에서 쿠키 삭제해도 서버에 세션 정보가 유지됨.

  • 단점

    • 서버 메모리 사용량이 증가합니다.

    • 확장성이 낮아 서버 간 세션 동기화가 필요할 수 있습니다.

3. Spring Security와 JWT를 사용한 로그인

Spring Security는 스프링 기반 애플리케이션의 보안을 강화하는 프레임워크입니다. JWT를 사용하면 인증 정보를 토큰 형태로 클라이언트에 저장하고 서버는 이를 검증하여 인증을 처리합니다.

  • 특징

    • 구성 요소:

      • JWT는 Header, Payload, Signature로 구성됩니다.

      • 클라이언트는 JWT를 HTTP 헤더의 Authorization 필드에 포함하여 요청합니다.

    • 저장 위치: 브라우저의 로컬 스토리지나 세션 스토리지.

    • 보안:

      • JWT 자체에 인증 정보를 포함하므로, 서버의 저장소를 사용하지 않습니다.

      • JWT는 서명을 통해 변조를 방지하지만, 탈취 시 악용될 수 있으므로 만료 시간을 설정해야 합니다.

예시 코드

// JWT 생성
String token = Jwts.builder()
    .setSubject("userId")
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간 유효
    .signWith(SignatureAlgorithm.HS256, "secretKey")
    .compact();

// JWT 검증
Claims claims = Jwts.parser()
    .setSigningKey("secretKey")
    .parseClaimsJws(token)
    .getBody();
String userId = claims.getSubject();
  • 장점

    • 서버 확장성과 성능이 우수.

    • 상태 비저장(stateless) 방식으로 서버 부하가 적음.

    • 클라이언트에서 인증 상태를 쉽게 확인할 수 있음.

  • 단점

    • 토큰 탈취 시 재발급 전까지 악용 가능.

    • 만료된 토큰을 처리하기 위한 별도 메커니즘이 필요.

    • 토큰 크기가 크면 네트워크 부하가 증가할 수 있음.

차이점 비교

구분쿠키 로그인세션 로그인Spring Security + JWT
저장 위치클라이언트 브라우저서버클라이언트 로컬/세션 스토리지
확장성높음낮음매우 높음
보안낮음비교적 높음중간~높음
상태 관리클라이언트에서 관리서버에서 관리상태 비저장
구현 복잡도낮음중간높음

💡 그렇다면 어떤 방식을 사용하는 것이 적합할까?

1. 단순하고 소규모 애플리케이션:

쿠키 로그인이 적합합니다. 구현이 간단하며 서버 자원을 많이 사용하지 않습니다.

2. 사용자 세션 관리가 중요한 경우:

세션 로그인이 적합합니다. 보안성이 높고, 서버 측에서 세션 정보를 효율적으로 관리할 수 있습니다.

3. 확장성과 성능이 중요한 대규모 애플리케이션:

Spring Security와 JWT를 사용하는 것이 적합합니다. 서버 확장이 용이하며, 클라이언트와 서버 간의 통신 부하를 줄일 수 있습니다.

-> 결론적으로, 애플리케이션의 규모, 요구사항, 보안 수준에 따라 적합한 방식을 선택해야 합니다. 대규모 분산 시스템에서는 JWT를 활용한 Spring Security가 가장 적합하며, 소규모 서비스에서는 쿠키나 세션 로그인도 충분히 효과적입니다.

profile
if (실패) { 다시 도전; } else { 성공; }

0개의 댓글