현대 백엔드 로드맵

📌 아래는 "클라이언트 → 프록시 서버 → 웹 서버 → WAS(웹 애플리케이션 서버) → RDS" 구조에서 각 파트의 역할과 특이점을 포함한 표입니다.


  하는 일 주요 역할 특이점
클라이언트 - HTTP 요청 생성 (예: HTML, API 호출)
- 브라우저, 모바일 앱, 또는 다른 서비스가 요청 전송
- 서버의 응답을 사용자에게 표시
- 데이터를 요청하는 주체.
- 사용자 인터페이스 제공.
- 서버로 요청하고 결과를 화면에 출력.
- 브라우저는 쿠키를 저장하고 필요 시 요청 시 함께 전송.
- 요청과 응답은 주로 HTTP/HTTPS 프로토콜을 통해 이루어짐.
프록시 서버 - 클라이언트 요청을 분석 및 필터링
- 로드 밸런싱: 요청을 여러 웹 서버로 분배
- 자주 요청되는 데이터 캐싱
- 보안 강화 (예: SSL 처리)
- 중개 역할: 클라이언트와 웹 서버 사이에서 요청 처리.
- 캐싱: 정적 리소스를 저장하여 빠른 응답.
- 트래픽 관리 및 부하 분산.
- 리버스 프록시로 동작, 클라이언트 IP를 숨김.
- HTTPS 요청을 웹 서버로 전달하기 전에 해독 가능 (SSL Termination).
웹 서버 - HTTP 요청 처리
- 정적 리소스(HTML, CSS, JS 등) 제공
- 동적 요청을 WAS로 전달
- 정적 리소스 제공.
- 요청이 정적인지 동적인지 구분.
- 동적 요청을 WAS로 전달하여 처리.
- 정적 리소스를 캐싱하여 빠르게 제공.
- Servlet 실행 기능 없음.
- 주로 Nginx, Apache가 사용됨.
필터 (WAS 내부) - HTTP 요청/응답 전처리 및 후처리
- JWT 등 인증/인가 처리
- 요청 로깅 및 데이터 변환
- 요청 흐름 제어: 요청을 허용하거나 차단.
- 공통 로직 처리: 여러 요청에서 반복되는 작업 처리.
- 보안: JWT 검증 및 세션 관리.
- Servlet 실행 전후로 동작.
- JWT 기반 인증 처리.
- 요청 데이터 로깅 및 변환.
- 응답 데이터에 헤더 추가 가능.
WAS (웹 애플리케이션 서버) - 클라이언트 요청 처리(예: 비즈니스 로직 실행)
- 데이터베이스와 통신하여 CRUD 작업 수행
- 요청 결과를 JSON, HTML 등으로 생성 및 반환
- 요청 처리: 클라이언트 요청에 따라 데이터를 생성, 수정, 조회, 삭제.
- 비즈니스 로직 구현.- RDS와 통신하여 필요한 데이터 제공.
- Servlet 컨테이너, 세션 포함.
- 쿠키/세션 관리 (예: HttpSession).
- JSP를 Servlet으로 변환하여 실행.
Servlet 컨테이너 - 클라이언트의 HTTP 요청을 처리하고 동적 콘텐츠 생성
- Servlet의 생명주기 관리 (init, service, destroy)
- 클라이언트 요청(예: GET, POST)을 받아 처리.
- 동적 웹 페이지 생성 (JSP 포함).
- WAS의 핵심 구성 요소.
- 스레드 풀을 사용하여 동시 요청 처리.
- 세션 상태 관리 기능 (HttpSession) 포함.
RDS (관계형 데이터베이스) - 데이터를 저장, 관리 및 조회
- SQL 쿼리 처리
- 요청 데이터를 반환하거나 저장
- 영구 데이터 저장.- SQL을 통해 데이터를 읽고 쓰는 작업 수행.
- 관계형 데이터베이스로 데이터 무결성 보장.
- 주로 MySQL, PostgreSQL, Oracle DB 사용.
- 데이터 모델은 테이블 형식으로 설계.
- WAS와 연결하여 데이터 CRUD 수행.

특이점 정리

  • 클라이언트:
    • 브라우저는 쿠키를 저장하고, 서버 요청 시 쿠키를 전송해 상태 관리.
    • HTTP/HTTPS 프로토콜로 요청과 응답을 주고받음.
  • 프록시 서버:
    • HTTPS 요청의 해독(SSL Termination) 역할 가능.
    • 리버스 프록시로 트래픽 부하 분산 및 클라이언트 IP 숨김.
  • 웹 서버:
    • 정적 리소스 캐싱 및 제공.
    • 동적 요청은 WAS로 전달.
  • WAS:
    • Servlet 컨테이너 포함.
    • 쿠키와 세션 관리 (HttpSession)을 통해 상태 유지.
    • 비즈니스 로직 처리 및 데이터베이스와 통신.
    • 랜더링
 

[Net] Rendering

Rendering📌 웹 애플리케이션에서 콘텐츠를 화면에 표시하는 과정을 의미합니다. 이 과정은 주로 웹 브라우저에서 일어나며, HTML, CSS, JavaScript 코드가 결합되어 최종적으로 사용자가 볼 수 있는 페

kyunghun0515.tistory.com

  • Servlet 컨테이너:
    • 동적 요청 처리의 핵심.
    • 세션과 쿠키 관리 기능 포함 (HttpSession 및 Cookie).
    • WAS 내부에서 동작하며 멀티스레드 요청 처리.
 

[Net] Servlet

Servlet📌 Servlet은 자바(Java) 언어로 작성된 서버 측 프로그램으로, 주로 웹 애플리케이션에서 클라이언트의 요청을 처리하고 동적으로 응답을 생성하는 데 사용됩니다. JAVA에서 Sevlet은 HttpServlet

kyunghun0515.tistory.com

 

  • RDS:
    • SQL 기반의 데이터 저장소.
    • 데이터의 영속성 보장 및 CRUD 처리.

쿠키와 세션 관리

  • 쿠키:
    • 클라이언트[ 웹 브라우저 ]에 저장되는 작은 데이터.
    • 클라이언트 상태를 서버에 전달하는 데 사용. (로그인 상태 유지등에 활용)
    • 보안에 취약하여 민감한 정보를 저장하지 않아야한다
    • 사용자 임의 수정이 가능하다..
    • 쿠키도 만료시간이 지정 가능하다. (만료 기간이 설정된 쿠키는 영속적 쿠키라 부른다.)
    • 만료 시간이 설정 안되면, 브라우저 종료시 삭제되는 세션 쿠키가 동작한다.
    • 예: 로그인 토큰, 사용자 설정.
 

[Net] Cookie

Cookie📌 사용자의 웹 브라우저에 저장되는 정보로 사용자의 상태 혹은 세션을 유지하거나 사용자 경험을 개선하기 위해 사용된다. 사용자 정보나 세션 데이터를 클라이언트(브라우저)에 저장하

kyunghun0515.tistory.com

 

  • 세션:
    • 서버에 저장되는 클라이언트 상태 정보.
    • 클라이언트를 고유하게 식별하기 위해 쿠키나 URL 파라미터로 세션 ID를 사용.
    • 서버에서 중요한 정보를 보관하며 로그인을 유지하는 형태로 쓰인다. Session ID를 탈취당해도 별 정보가 없어 상대적으로 안전하다.
    • 만료 시간을 설정해서 탈취 문제를 최소화 가능하다.
      • HttpSession은 최근 Session을 요청한 시간을 기준으로 만료 시간을 유지한다.
    • 브라우저가 아닌 서버에서 관리하는 만큼, 브라우저가 꺼져도 유지된다.
    • 예: 로그인 상태 유지, 장바구니 정보.

필터

  1. 동작 위치:
    • WAS 내부에서 Servlet 실행 전후에 동작.
    • 클라이언트 요청과 WAS의 비즈니스 로직 사이에서 요청/응답을 전처리/후처리.
  2. 역할:
    • JWT 인증/인가: Authorization 헤더의 JWT를 검증하여 요청 허용 여부 결정.
    • 요청 로깅: 요청 URL, 헤더, 본문 등을 로깅하여 분석 및 디버깅.
    • 응답 로깅: 클라이언트로 전송되는 응답 데이터를 로깅.
    • 공통 로직 처리: 요청 데이터 변환, 헤더 추가, 응답 데이터 가공.
  3. 특이점:
    • 필터는 모든 요청에 대해 공통적으로 동작할 수 있도록 설계되므로, 반복적인 로직을 중앙에서 처리 가능.
    • Spring Security와 연동하여 인증/인가 로직을 필터로 구현 가능.
 

[Net] Filter

공통 관심 사항(cross-cutting concerns)📌 애플리케이션 전반에 걸쳐 여러 모듈이나 레이어에서 공통적으로 필요하지만, 특정 비즈니스 로직과 직접적으로 관련이 없는 기능을 의미합니다. 이러한

kyunghun0515.tistory.com

 

 

현대 데이터 통신 형태

"클라이언트 → 프록시 서버 → 웹 서버 → WAS(웹 애플리케이션 서버)"에서 클라이언트->서버에서 데이터 요청, 전송시에 사용되는 기술의 이야기

 

아래는 RESTful API, JWT(토큰), HTTP 메서드, HTTP 헤더에 관한 설명과 이들 간의 연관성을 정리한 표

 

  개념 설명 주요 역할 연관성
RESTful API - 자원을 URI로 식별하고, HTTP 메서드로 자원을 조작하는 아키텍처 스타일.
- Stateless 방식으로 동작.
- 클라이언트, 서버 간 데이터 교환 표준.
- CRUD 작업을 HTTP 메서드로 정의.
- 요청과 응답을 HTTP 프로토콜로 전달.
- HTTP 메서드와 헤더를 사용해 자원 조작.
- 헤더를 통해 JWT 인증 및 데이터 형식을 관리.
- Stateless 특성을 JWT와 결합.
JWT (JSON Web Token) - Stateless 인증 방식으로 클라이언트의 인증 정보를 서버가 아닌 클라이언트에 저장.
- Header, Payload, Signature로 구성.
- 클라이언트 인증 및 권한 부여.
- 서버가 상태를 저장하지 않아 확장성 높음.
- RESTful API의 Stateless 특성을 지원.
- HTTP 헤더(Authorization)에 포함되어 전달.- RESTful API 요청에서 인증 및 권한 부여에 사용.
- 데이터 보호를 위해 HTTP Secure(HTTPS)와 함께 사용 권장.
HTTP 메서드 - HTTP 프로토콜에서 자원을 조작하는 메서드 (GET, POST, PUT, DELETE, PATCH 등). - CRUD 작업 정의:
- GET: 자원 조회.
- POST: 자원 생성.
- PUT: 자원 수정.
- DELETE: 자원 삭제.
- RESTful API의 자원 조작 방식을 정의.
- 헤더와 결합해 데이터 형식 지정 (예: Content-Type).
- 인증된 요청에서만 동작하도록 JWT 검증과 함께 사용.
HTTP 헤더 - HTTP 요청 및 응답의 메타데이터를 제공.
- 데이터 형식, 인증 정보, 캐싱 정책 등을 포함.
- 인증 정보 전달 (예: Authorization: Bearer <JWT>).
- 데이터 형식 정의 (Content-Type, Accept).
- RESTful API와 JWT 인증에 사용.
- Authorization 헤더로 토큰 전달.
- 요청과 응답 데이터의 형식을 제어하여 클라이언트-서버 간 호환성 보장.

연관성 및 흐름 요약

RESTful API:

  • HTTP 메서드로 자원 조작을 정의.
  • HTTP 헤더를 통해 인증(JWT) 및 데이터 형식(Content-Type)을 관리.
  • Stateless 특성 유지.

 Token

  • 인증/인가 과정에서 사용되며 사용자 또는 시스템의 신원과 권한을 증명하고 요청의 유효성을 검증하는 데 사용되는 디지털 문자열
  • Session과는 다르게 Client가 데이터(Token)를 저장하고 있다.
    • Stateless를 기반으로 하여 확장성이 뛰어나다.
  • Mobile과 같이 Cookie를 사용할 수 없는 경우에도 사용할 수 있다.
  • Payload는 암호화되지 않는다.
  • 만료 시간으로 Token 탈취를 대비한다.
 

[Net] Token & JWT

Token📌 Web Application이나 API에서 인증(Authentication)과 인가(Authorization) 과정에서 사용되며 사용자 또는 시스템의 신원과 권한을 증명하고 요청의 유효성을 검증하는 데 사용되는 디지털 문자열이

kyunghun0515.tistory.com

 

JWT

  • 인증에 필요한 정보들을 암호화시킨 JSON 형태의 Token
  • Signature를 통해 Token을 안전하게 관리한다.
  • JWT의 목적은 정보 보호가 아닌, 위조 방지에 있다.
  • HTTP 헤더(Authorization)로 전달.
  • RESTful API 요청에서 클라이언트 인증과 권한 부여에 사용.
  • Stateless 특성을 유지하여 서버 상태 관리의 부담을 줄임.

HTTP 메서드:

  • RESTful API의 자원 조작 방식을 정의.
  • 요청 시 헤더(Content-Type, Authorization)와 결합하여 요청 처리.

HTTP 헤더:

  • HTTP 요청/응답의 메타데이터 제공.
  • JWT를 Authorization 헤더에 포함해 인증 정보를 전달.
  • 데이터 형식(Content-Type, Accept)을 설정해 클라이언트-서버 간 데이터 교환 정의.

예시: RESTful API 요청과 흐름

  1. 클라이언트가 RESTful API 요청:
  2. POST /api/products HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... Content-Type: application/json
  3. JWT 인증:
    • 서버는 Authorization 헤더에서 JWT를 추출.
    • JWT를 검증하여 클라이언트의 권한 확인.
  4. HTTP 메서드:
    • 요청이 POST 메서드임을 확인.
    • 자원 생성 로직 실행.
  5. 응답:
  6. HTTP/1.1 201 Created Content-Type: application/json { "id": 123, "name": "New Product", "price": 50.0 }

결론

  • RESTful API는 HTTP 메서드와 헤더를 통해 자원을 조작하며, Stateless 특성을 유지.
  • JWT는 인증과 권한 부여를 처리하며, HTTP 헤더(Authorization)를 통해 전달.
  • HTTP 메서드와 헤더는 RESTful API와 JWT가 효율적으로 동작하도록 결합되어 사용
    이 구조를 통해 클라이언트-서버 간의 효율적이고 안전한 데이터 교환이 가능

 

추가 설명

  1. 네트워크 통신은 HTTP로 이루어진다.
  2. HTTP는 무상태 프로토콜이며 비연결성 특징을 가지고 있다.
  3. HTTP Message 구조
    1. HTTP Method
    2. 상태코드
    3. HTTP Header
  4. HTTP API는 Restful 하게 설계해야 한다. 최소 성숙도레벨 2를 지켜야 한다.
  5. Servlet은 Java에서 Request, Response를 쉽게 다루게 해주는 객체이다.
  6. Servlet Container는 Servlet 객체를 싱글톤으로 관리한다.
  7. WAS는 다중 요청 처리를 위해 Multi Thread를 지원한다.
  8. SSR 방식은 서버에서 동적인 페이지를 완성하여 응답한것을 브라우저에서 화면을 출력한다.

CSR은 HTTP API 통신으로 얻은 결과를 통해 브라우저에서 동적으로 화면을 출력한다.

 

[1] 네트워크 기본 개념

  • Packet: 데이터는 패킷이라는 작은 단위로 쪼개져 전송됩니다. 패킷은 헤더, 페이로드, 트레일러로 구성되며, 패킷을 구성하는 각 요소는 데이터가 정확하게 전송되도록 돕습니다.
    • 배달 예시: 패킷은 배달되는 소포에 해당합니다. 소포는 수신자의 이름과 주소(헤더), 내용물(페이로드), 배송 확인 스티커(트레일러)가 있습니다.
  • HTTP: HyperText Transfer Protocol 에서 데이터를 주고받는 프로토콜입니다. 클라이언트와 서버 간의 요청과 응답 방식으로 동작합니다.
    • 배달 예시: HTTP는 배달 요청서 배송 알림에 해당합니다. 클라이언트가 요청서를 보내면 서버는 해당 요청에 맞는 배송 알림을 보냅니다.
  • DNS (Domain Name System): DNS는 도메인 이름을 IP 주소로 변환하는 시스템입니다.
    • 배달 예시: DNS는 배달에 필요한 주소 안내서와 같습니다. 클라이언트가 도메인 이름을 입력하면, DNS는 그것을 실제 주소로 바꿔주는 역할을 합니다.
  • URI (Uniform Resource Identifier): URI는 웹 자원의 주소를 식별하는 방법입니다.
    • 배달 예시: URI는 배달 주소와 같습니다. 웹 자원을 정확하게 식별하고 위치를 알려줍니다.
  • Port: 네트워크 통신에서 특정 애플리케이션을 식별하는 숫자입니다.
    • 배달 예시: 포트는 집의 방 번호와 같습니다. 소포가 도착한 주소에서 어떤 방으로 가야 할지 알려줍니다.
  • Cache: 캐시는 자주 사용하는 데이터를 임시 저장하여 빠르게 접근할 수 있도록 돕습니다.
    • 배달 예시: 캐시는 자주 사용하는 물건을 미리 준비해두고, 필요할 때 바로 꺼내서 배송하는 것과 같습니다.

[2] 웹 서버와 WAS (Web Application Server)

  • Web Server: 웹 서버는 클라이언트의 요청을 받아 **정적 파일(HTML, CSS, JS)**을 응답하는 서버입니다.
    • 배달 예시: 웹 서버는 택배 회사입니다. 택배 회사는 소포를 받은 후, 내용물이 정해져 있는 소포를 정확하게 배달합니다.
  • WAS (Web Application Server): WAS는 동적인 웹 애플리케이션을 처리하는 서버로, 웹 서버보다 더 복잡한 비즈니스 로직을 처리합니다.
    • 배달 예시: WAS는 주문을 받고 복잡한 가공을 거쳐 배송하는 업체입니다. 클라이언트가 주문한 후, 상품을 가공하여 최종 결과물을 배송합니다.

[3] HTTP와 관련된 개념들

  • HTTP Method: HTTP 요청의 유형에는 GET, POST, PUT, DELETE 등이 있습니다.
    • 배달 예시: HTTP 메서드는 배달 요청 유형입니다. 예를 들어, GET은 단순히 "배달해주세요", POST는 "새로운 주문을 넣어주세요"와 같습니다.
  • HTTP Header: HTTP 헤더는 요청이나 응답에서 추가적인 정보를 담고 있는 부분입니다.
    • 배달 예시: 헤더는 배달 시 필요한 추가 정보입니다. 예를 들어, 요청자가 주문한 물건에 대한 배달 주소, 연락처 같은 정보입니다.
  • Cookie: 쿠키는 클라이언트 측에 저장된 세션 정보입니다.
    • 배달 예시: 쿠키는 배달 중간에 발생하는 특별한 메모입니다. 배달 중에 클라이언트가 이전 정보를 기억하여 다시 요청할 수 있게 돕습니다.
  • Cache: 캐시는 자주 요청되는 데이터를 로컬에 저장하여 응답 속도를 빠르게 만듭니다.
    • 배달 예시: 캐시는 자주 받는 물건을 미리 준비해 놓고 필요할 때 빠르게 배송하는 것과 같습니다.
  • Redirection (리다이렉션): 리다이렉션은 사용자가 요청한 자원이 다른 위치로 이동했을 때, 해당 자원을 새로운 위치로 안내하는 과정입니다.
    • 배달 예시: 리다이렉션은 주소지가 변경된 경우 새 주소로 다시 안내하는 것입니다.

[4] 서버와 클라이언트의 렌더링 방식

  • CSR (Client-Side Rendering): CSR은 클라이언트에서 HTML을 동적으로 생성하여 렌더링하는 방식입니다.
    • 배달 예시: CSR은 클라이언트가 주문을 받고 상품을 준비하여 직접 배달하는 것과 같습니다.
  • SSR (Server-Side Rendering): SSR은 서버에서 HTML을 미리 생성하여 클라이언트에게 전달하는 방식입니다.
    • 배달 예시: SSR은 서버가 모든 물건을 미리 포장하여 클라이언트에게 빠르게 배송하는 방식입니다.

[5] WAS 생명주기 모델

  • 생명주기: WAS의 생명주기는 애플리케이션의 시작, 실행, 종료 순으로 진행됩니다.
    • 배달 예시: WAS의 생명주기는 배달 준비 과정에 해당합니다. 주문 받기 → 배달 준비 → 배달 완료의 과정입니다.

[6] Thread와 관련된 개념들

  • Thread: 쓰레드는 프로그램 내에서 실행 단위를 말하며, 여러 쓰레드가 동시에 작업을 처리할 수 있습니다.
    • 배달 예시: 쓰레드는 여러 명의 배달 기사가 동시에 여러 주소로 배달하는 것에 해당합니다.
  • Servlet: 서블릿은 웹 애플리케이션 서버에서 요청을 처리하는 Java 기반의 기술입니다.
    • 배달 예시: 서블릿은 배달 기사가 주문을 받고, 그에 맞는 작업을 처리하여 고객에게 전달하는 역할입니다.

[7] 다른 주요 개념들

  • MSA (Microservices Architecture): MSA는 마이크로서비스 아키텍처로, 큰 애플리케이션을 작은 서비스들로 분할하여 관리하는 방법입니다.
    • 배달 예시: MSA는 여러 개의 물류 창고에서 각각의 물건을 처리하고, 모든 창고가 협력하여 배달을 완성하는 것과 같습니다.
  • Scale Up, Scale Out: Scale Up은 하드웨어 성능을 강화하는 방식이고, Scale Out은 서버를 추가하는 방식입니다.
    • 배달 예시: Scale Up은 더 큰 트럭을 구입하는 것이고, Scale Out은 배달 기사를 더 추가하는 것과 같습니다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Filter  (1) 2025.01.01
[Net] Session & Cookie의 관계  (0) 2024.12.31
[Net] Token & JWT  (0) 2024.12.29
[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13

공통 관심 사항(cross-cutting concerns)

📌 애플리케이션 전반에 걸쳐 여러 모듈이나 레이어에서 공통적으로 필요하지만, 특정 비즈니스 로직과 직접적으로 관련이 없는 기능을 의미합니다.

  • 이러한 기능은 여러 곳에서 반복적으로 사용되며, 코드 중복을 초래하거나 모듈 간의 결합도를 높이는 원인이 될 수 있습니다.
같은 말로 횡단 관심사 라고 하며 여러 위치에서 공통적으로 사용되는 부가 기능이고 Filter가 나오게된 이유는 공통 관심사(Cross Cutting Concern)의 처리 때문이다.

 

요구사항 : 로그인 한 유저만 특정 API를 사용할 수 있어야 한다.
  • 해결방법
    • 언제나 핵심은 수정에 있다!
    1. 화면에서 로그인 하지 않으면 API를 사용하지 못하도록 막는다.
      • 유저가 HTTP 요청을 마음대로 조작할 수 있다.
    2. Controller에서 로그인 여부를 체크하는 Logic을 작성한다.
      • 실제로는 인증이 필요한 모든 컨트롤러에 공통으로 로그인 여부를 체크해야 한다.
      • 로그인 로직이 변경될 때 마다 로그인 여부를 체크하는 Logic 또한 변경될 가능성이 높다.
@RestController
@RequestMapping("/post")
public class PostController {

    @PostMapping
    public PostResponseDto create(PostCreateRequestDto request) {
        // 로그인 여부 확인 로직

        // 생성 로직
    }

    @PutMapping("/{postId}")
    public void update(
            @PathVariable Long postId,
            PostUpdateRequestDto request
    ) {
        // 로그인 여부 확인 로직
        // 수정 로직
    }

    @DeleteMapping("/{postId}")
    public void delete(@PathVariable Long postId) {
        // 로그인 여부 확인 로직
        // 삭제 로직
    }

}
  • 위와같이 여러가지 로직에서 공통으로 관심이 있는 부분을 공통 관심사 라고 한다.
로그인 여부 확인 로직 -> 공통 관심사 (인증 : 로그인)
  • 공통 관심사는 로그인뿐만 아니라 더 큰범위를 의미한다.
  1. Spring AOP를 활용할 수 있다.
  2. Web과 관련된 공통 관심사는 Servlet FilterSpring Intercepter를 사용한다.
    • HttpServletRequest 객체를 제공하기 때문에 HTTP 정보나 URL 정보에 접근하기 쉽다.
    ex) HTTP Header Cookie → 인증
  3. ex ) 특정 URL의 요청은 인증을 할것이다. → URL 정보 필요

 

 

Spring AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)

📌 로깅, 보안, 트랜잭션 관리 등과 같은 횡단 관심사를 개별적인 Aspect(관점)로 모듈화할 수 있도록 합니다.

  • 이를 통해 핵심 비즈니스 로직과 부가적인 로직을 분리하여 코드의 가독성과 유지보수성을 높일 수 있습니다.
  • 반복되는 공통 작업(예: 로깅, 보안, 트랜잭션 관리)을 한 곳에 모아서 관리할 수 있게 도와준다. 예를 들어 모든 메서드 실행 전에 로그를 냄기는 경우, 각 메서드에 System.out.println()을 넣는 대신, AOP로 한번만 설정하면 알아서 모든 메서드에 적용된다.

 

Spring AOP의 주요 개념

  1. Aspect(관점)
    • 횡단 관심사를 정의한 모듈입니다. 예: 로그 기록, 트랜잭션 관리.
  2. Join Point(조인 포인트)
    • 애플리케이션 실행 과정에서 Aspect를 적용할 수 있는 지점입니다. 예: 메서드 호출, 예외 발생.
  3. Advice(어드바이스)
    • Join Point에서 실행되는 작업(Aspect의 구체적인 동작)입니다. Advice는 다음과 같이 구분됩니다:
      • Before: 메서드 실행 전에 실행.
      • After: 메서드 실행 후에 실행.
      • Around: 메서드 실행 전후에 실행.
      • After Returning: 메서드가 정상적으로 반환된 후 실행.
      • After Throwing: 메서드 실행 중 예외가 발생한 후 실행.
  4. Pointcut(포인트컷)
    • Advice가 적용될 Join Point를 정의하는 표현식입니다.
  5. Weaving(위빙)
    • Aspect를 애플리케이션의 대상 객체에 적용하는 과정입니다. Spring AOP에서는 런타임 위빙이 일반적으로 사용됩니다.

 

Spring AOP 특징

  • Spring AOP는 프록시 기반으로 동작합니다.
  • 런타임 기반 AOP를 지원하며, Java 동적 프록시나 CGLIB를 사용합니다.
  • 메서드 호출 수준의 AOP를 제공합니다. (클래스 내부의 필드 변경 등에는 적용되지 않음)

 

Spring AOP 사용 방법

1. 의존성 추가 Spring AOP를 사용하려면 Maven 또는 Gradle에 관련 의존성을 추가합니다:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>버전</version>
</dependency>

 

2. Aspect 정의 아래는 간단한 로그 Aspect 예제입니다:

@Aspect
@Component
public class LoggingAspect {
    
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("메서드 실행 전: " + joinPoint.getSignature().getName());
    }
    
    @After("execution(* com.example.service.*.*(..))")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("메서드 실행 후: " + joinPoint.getSignature().getName());
    }
}

 

3. Pointcut 표현식

  • execution(* 패키지명.클래스명.메서드명(..)): 특정 메서드에 적용.
  • within(패키지명..*): 특정 패키지 내 모든 클래스에 적용.
  • @annotation(애너테이션): 특정 애너테이션이 적용된 메서드에만 적용.

4. AOP 활성화 AOP 기능을 활성화하려면 @EnableAspectJAutoProxy 애너테이션을 사용합니다:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

 

 

Proxy

📌 대리자라는 의미로, 컴퓨터 네트워킹에서 주로 클라이언트와 서버 간의 중간에 위치하여 데이터를 중계하는 서버 또는 소프트웨어를 지칭합니다.

 

1. 프록시의 주요 개념

  • 중간자 역할: 프록시는 클라이언트가 서버에 직접 요청을 보내지 않고, 프록시를 통해 요청과 응답이 오가게 만듭니다.
  • 주소 은폐: 클라이언트의 실제 IP 주소를 감추고, 프록시 서버의 IP를 사용하여 요청을 처리합니다.
  • 트래픽 제어: 요청을 필터링하거나 캐싱하는 등 트래픽을 관리합니다.

2. 프록시의 유형

1) 포워드 프록시 (Forward Proxy)

  • 동작: 클라이언트가 프록시 서버를 통해 인터넷에 요청을 보냅니다.
  • 사용 사례:
    • IP 숨김: 사용자의 IP 주소를 감추고 다른 주소로 대체.
    • 콘텐츠 우회: 지역 제한된 콘텐츠(예: 특정 국가에서 차단된 웹사이트) 접근.
    • 캐싱: 자주 요청되는 데이터를 저장하여 빠른 응답 제공.

2) 리버스 프록시 (Reverse Proxy)

  • 동작: 서버 앞단에 위치하며, 클라이언트 요청을 받아 적절한 서버에 전달.
  • 사용 사례:
    • 로드 밸런싱: 여러 서버로 트래픽을 분산하여 서버 과부하 방지.
    • 보안: 서버의 실제 위치(IP)를 숨기고 공격으로부터 보호.
    • SSL 종단: HTTPS 암호화를 처리하여 서버 부담 감소.

3) 오픈 프록시 (Open Proxy)

  • 동작: 전 세계 누구나 사용할 수 있는 공개 프록시 서버.
  • 특징: 익명성을 제공하지만 보안 문제가 있을 수 있음.
  • 주의사항: 악의적인 활동에 이용될 가능성이 높음.

4) 투명 프록시 (Transparent Proxy)

  • 동작: 사용자에게 보이지 않는 방식으로 트래픽을 중계.
  • 사용 사례:
    • 네트워크 관리자에 의해 웹 필터링이나 모니터링.
    • 기업 및 공공기관에서 사용.

5) SOCKS 프록시

  • 특징: TCP와 UDP 트래픽을 모두 처리 가능.
  • 사용 사례:
    • P2P 파일 공유(예: 토렌트).
    • 게임에서 지연 감소 및 지역 제한 우회.

6) VPN과의 차이

  • VPN은 네트워크 트래픽 전체를 암호화하는 반면, 프록시는 특정 트래픽만 처리.
  • 프록시는 보안보다는 익명성과 요청 중계를 중심으로 함.

3. 프록시 사용 사례

  1. 보안 및 익명성 제공
    • 사용자의 실제 IP를 숨기고, 온라인 활동을 익명으로 수행.
  2. 콘텐츠 필터링 및 접근 제한
    • 기업이나 학교에서 불법적이거나 부적절한 콘텐츠 접근 차단.
  3. 지역 제한 콘텐츠 우회
    • 예: 특정 국가에서 차단된 Netflix 콘텐츠를 시청.
  4. 트래픽 최적화
    • 캐싱을 통해 대역폭을 줄이고, 요청 속도를 높임.
  5. 분산 처리
    • 리버스 프록시를 사용하여 대규모 트래픽을 여러 서버로 나누어 처리.
  6. 데이터 로깅 및 모니터링
    • 네트워크 트래픽 분석 및 기록.
  7. 테스트 및 디버깅
    • 웹 개발에서 네트워크 요청과 응답을 확인하거나 조작.

4. 프록시 사용 시 고려사항

  1. 성능:
    • 추가적인 네트워크 홉으로 인해 지연이 발생할 수 있음.
  2. 보안:
    • 신뢰할 수 없는 프록시 서버 사용 시 개인 정보가 유출될 위험.
  3. 법적 문제:
    • 지역 제한 콘텐츠 우회 등은 해당 국가의 법률을 위반할 수 있음.
  4. 설정 복잡성:
    • 특정 애플리케이션이나 네트워크 환경에서는 복잡한 설정이 필요할 수 있음.

 

아래는 **프록시(Proxy)**와 유사 기술(VPN, NAT, 방화벽 등)을 비교한 표입니다. 각 기술의 특징, 주 용도, 장단점을 기준으로 작성했습니다.

기술 주요 특징 주 용도 장점 단점
프록시 (Proxy) 클라이언트와 서버 간의 중계 역할. 특정 요청과 응답만 처리. 익명성 제공, 콘텐츠 필터링, 캐싱, 로드 밸런싱 익명성 제공, 특정 요청만 중계 가능, 네트워크 효율성 증대 암호화 부족, 전체 트래픽 보호 불가, 설정 복잡도
VPN 클라이언트와 서버 간의 모든 네트워크 트래픽을 암호화된 터널을 통해 전송. 전체 트래픽 보호, 지역 제한 우회, 공공 네트워크 보안 강력한 암호화, 전체 네트워크 보호, 위치 은폐 느린 속도(암호화로 인한 지연), 서버 설정 복잡도
NAT 내부 네트워크의 사설 IP를 공인 IP로 변환하여 인터넷 접속을 가능하게 함. 내부 네트워크 주소 은폐, 인터넷 접속 공유 네트워크 자원 효율적 사용, 기본적인 보안 제공 특정 연결 설정 어려움(포트 포워딩 필요), 정교한 보안 기능 부족
방화벽 (Firewall) 네트워크 트래픽을 모니터링하고, 사전 정의된 규칙에 따라 허용 또는 차단. 네트워크 보안, 공격 방지, 접근 제어 높은 보안성, 트래픽 모니터링 가능 설정 복잡도, 성능 저하 가능
CDN 클라이언트 요청을 가장 가까운 서버로 라우팅하여 콘텐츠를 빠르게 제공. 콘텐츠 전송 속도 향상, 대규모 트래픽 처리 빠른 속도, 지연 시간 감소, 서버 부하 감소 실시간 처리 제한, 동적 콘텐츠 캐싱 어려움
로드 밸런서 여러 서버에 네트워크 트래픽을 분산하여 서버의 부하를 줄임. 서버 성능 최적화, 고가용성 제공 서버 부하 감소, 고가용성 제공 초기 설정 복잡, 추가 하드웨어/소프트웨어 필요
TOR (Onion Routing) 익명 네트워크로 트래픽을 여러 노드에 암호화해 전송하여 사용자의 위치와 활동을 감춤. 높은 익명성 제공, 검열 우회 익명성 보장, 검열 우회 가능 느린 속도, 네트워크 신뢰성 부족, 악성 노드 가능성
SOCKS 프록시 TCP 및 UDP 트래픽 모두 지원하며, 특정 애플리케이션 트래픽만 중계. P2P 파일 공유, 게임 지연 감소, 특정 트래픽 익명화 유연성 높음, 애플리케이션별 설정 가능 암호화 부족, 전체 네트워크 보호 불가

 

 

Servlet Filter

📌 클라이언트의 요청(request) 및 응답(response)을 처리하거나 조작하기 위해 사용되는 컴포넌트( 소프트웨어 개발에서 재사용 가능하고 독립적인 기능 단위 )

  • Servlet Filter는 보안, 로깅, 인코딩, 인증/인가 등 다양한 작업을 처리하기 위해 사용된다.

 

 

Servlet Filter 특징

  1. 공통 관심사 로직 처리
    • 공통된 로직을 중앙 집중적으로 구현하여 재사용성이 높고 유지보수가 쉽다.
    • 모든 요청이 하나의 입구를 통해 처리되어 일관성을 유지한다.
  2. HTTP 요청 및 응답 필터링
  3. Filter Chain
    • 여러 개의 필터가 순차적으로 적용될 수 있다.
    • filterChain.doFilter(request, response); 다음 필터로 제어를 전달한다.
  4. doFilter()
    • 실제 필터링 작업을 수행하는 주요 메소드로 필터가 처리할 작업을 정의한다.
    • 다음 필터로 제어를 넘길지 여부를 결정한다.

 

Servlet Filter 적용

  • Filter를 적용하면 Servlet이 호출되기 이전에 Filter를 항상 거치게된다.
  • 공통 관심사를 필터에만 적용하면 모든 요청 or 응답에 적용된다 .
  • Filter는 특정 URL Pattern에 적용할 수 있다.
  • Spring을 사용하는 경우 Servlet은 **Dispatcher Servlet**이다.

 

Servlet Filter와 Servlet의 차이점

항목Servlet FilterServlet

주요 목적 요청/응답 전후의 처리 클라이언트 요청을 처리하고 응답 생성
체인 가능성 여러 필터를 체인 방식으로 연결 가능 독립적으로 동작
적용 대상 서블릿, JSP, 정적 리소스 등 모든 요청 특정 URL에 대한 요청만 처리
작업 위치 요청/응답 전후 요청 처리 내부

 

Servlet Filter와 Listener 비교

항목Servlet FilterServlet Listener

주요 역할 요청/응답 흐름을 가로채고 처리 특정 이벤트(애플리케이션, 세션 등) 처리
적용 대상 클라이언트 요청/응답 흐름 컨텍스트, 세션, 요청 수명 주기
예제 로깅, 인증, 캐싱 세션 생성/소멸, 애플리케이션 초기화

 

 

 

Filter Interface

📌 Java Servlet에서 HTTP 요청과 응답을 중간에서 처리, 이를 기반으로 다양한 처리 작업을 수행하는 데 사용되는 Interface이다.

  • 클라이언트 → 요청 → 필터 → 서블릿/JSP → 응답 → 필터 → 클라이언트

 

Filter Interface의 사용 사례

  1. 인증(Authentication) 및 권한 부여(Authorization):
    • 특정 페이지에 접근하려는 클라이언트를 필터에서 확인하고, 인증되지 않은 사용자라면 로그인 페이지로 리디렉션.
  2. 로깅(Logging):
    • 요청의 정보를 기록(예: 요청 URL, 클라이언트 IP, 요청 시간 등).
  3. 데이터 유효성 검사:
    • 클라이언트의 요청 데이터를 확인하고, 잘못된 값이 있으면 필터 단계에서 차단.
  4. 응답 데이터 변환:
    • 서버의 응답 데이터를 필터에서 압축하거나 특정 포맷(예: JSON)으로 변환.
  5. 보안 처리:
    • HTTP 요청의 헤더를 검사해 보안 위협(예: XSS, CSRF)을 탐지 및 차단.

 

jakarta.servlet.Filter

  • Filter Interface를 Implements하여 구현하고 Bean으로 등록하여 사용한다.
    • Servlet Container가 Filter를 Singleton 객체로 생성 및 관리한다.

 

주요 메서드

  1. init()
    • Filter를 초기화하는 메서드이다.
    • Servlet Container가 생성될 때 호출된다.
    • default ****method이기 때문에 implements 후 구현하지 않아도 된다.
  2. doFilter()
    • Client에서 요청이 올 때 마다 doFilter() 메서드가 호출된다.
      • doFilter() 내부에 필터 로직(공통 관심사 로직)을 구현하면 된다.
    • WAS에서 doFilter() 를 호출해주고 하나의 필터의 doFilter()가 통과된다면
    • Filter Chain에 따라서 순서대로 doFilter() 를 호출한다.
    • 더이상 doFilter() 를 호출할 Filter가 없으면 Servlet이 호출된다.
  3. destroy()
    • 필터를 종료하는 메서드이다.
    • Servlet Container가 종료될 때 호출된다.
    • default method이기 때문에 implements 후 구현하지 않아도 된다.

 

 

Servlet Filter 구현

  • Filter 구현체
    • 요청 URL을 Log로 출력하는 Filter
@Slf4j
public class CustomFilter implements Filter {
    @Override
    public void doFilter(
            ServletRequest request,
            ServletResponse response,
            FilterChain chain
    ) throws IOException, ServletException {

        // Filter에서 수행할 Logic
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        log.info("request URI={}", requestURI);
        // chain 이 없으면 Servlet을 바로 호출
        chain.doFilter(request, response);
    }
}

doFilter() 는 더 이상 호출할 Filter가 없다면 Servlet을 호출한다.

ServletRequest 는 기능이 별로 없어서 대부분 기능이 많은 HttpServletRequest 를 다운 캐스팅 하여 사용한다.

 

 

Filter 등록

@Configuration
public class WebConfig implements WebMvcConfigurer {
		
		@Bean
		public FilterRegistrationBean customFilter() {
				FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
				// Filter 등록
				filterRegistrationBean.setFilter(new CustomFilter());
				// Filter 순서 설정
				filterRegistrationBean.setOrder(1);
				// 전체 URL에 Filter 적용
				filterRegistrationBean.addUrlPatterns("/*");
				
				return filterRegistrationBean;
		}
}
  • setFilter()
    • 등록할 필터를 파라미터로 전달하면 된다.
  • setOrder()
    • Filter는 Chain 형태로 동작한다.
    • 즉, 실행될 Filter들의 순서가 필요하다.
    • 파라미터로 전달될 숫자에 따라 우선순위가 정해진다.
    • 숫자가 낮을수록 우선순위가 높다.
  • addUrlPatterns()
    • 필터를 적용할 URL 패턴을 지정한다.
    • 여러개 URL 패턴을 한번에 지정할 수 있다.
    • 규칙은 Servlet URL Pattern과 같다.
  • filterRegistrationBean.addUrlPatterns("/*")
    • 모든 Request는 Custom Filter를 항상 지나간다.
Spring이 제공하는 URL Pattern은 Servlet과 다르게 더욱 세세하게 설정할 수 있다.

 

 

 

Servlet Filter 정리

  1. Filter를 사용하려면 Filter Interface를 Implements 하여 구현한다.
  2. 구현한 Filter를 Bean으로 등록 한다.
  3. HTTP 요청이 오면 doFilter() 메서드가 호출된다.
    • ServletRequest는 기능이 별로 없어서 HttpServletRequest로 다운 캐스팅 해야한다.
  4. chain.doFilter(request, response)
    • (순서를 설정해둔)다음 필터가 있으면 Filter를 호출한다.
    • 다음 실행할 필터가 없으면 Servlet을 호출한다.
    • 해당 메서드를 호출하지 않으면 다음 단계로 진행되지 않는다.
      • 다음 필터나 Servlet을 호출하지 않는다.
  5. Filter를 등록하는 방법은 여러가지가 있다.
    • SpringBoot의 경우 FilterRegistrationBean 을 사용한다.

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] 네트워크 요약  (1) 2025.01.22
[Net] Session & Cookie의 관계  (0) 2024.12.31
[Net] Token & JWT  (0) 2024.12.29
[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13

세션과 쿠키는 항상 함께 다니는 이유는, 세션이 동작하는 데 쿠키가 필요한 경우가 많기 때문입니다.


1. 세션과 쿠키의 관계

세션과 쿠키는 역할이 다름

  • 세션은 서버에서 클라이언트를 관리하기 위해 사용하는 데이터입니다.
  • 쿠키는 클라이언트(브라우저)에 데이터를 저장하기 위해 사용하는 기술입니다.

왜 세션에 쿠키가 필요할까?

  • 세션은 클라이언트를 식별하기 위해 세션 ID를 발급합니다.
  • 세션 ID를 클라이언트와 서버 간에 주고받아야 세션 상태를 유지할 수 있습니다.
  • 쿠키는 이 세션 ID를 클라이언트 측에 저장하고, 이후 요청마다 서버로 전달하는 데 사용됩니다.

2. 세션과 쿠키가 항상 같이 다니는 이유

  1. 세션 ID 전달
    • 서버는 클라이언트를 식별하기 위해 세션 ID를 발급하고, 이를 클라이언트에 저장해야 합니다.
    • 세션 ID를 저장하고 서버로 다시 전달하는 가장 일반적인 방법이 쿠키입니다.
    • :
      HTTP/1.1 200 OK
      Set-Cookie: JSESSIONID=abcd1234; Path=/; HttpOnly
      
  2. 자동 관리
    • 쿠키는 브라우저가 자동으로 관리하므로, 클라이언트가 따로 세션 ID를 전송하지 않아도 브라우저가 요청마다 서버로 쿠키를 전송합니다.
    • :
      GET /profile HTTP/1.1
      Host: example.com
      Cookie: JSESSIONID=abcd1234
      
  3. 보안 및 편의성
    • 세션 ID를 URL로 전달하는 방법(예: URL Rewriting)은 보안 문제와 관리상의 불편함이 있습니다.
    • 쿠키를 사용하면 세션 ID가 URL에 노출되지 않아 보안성이 더 높습니다.

3. 세션 사용 시 쿠키를 따로 저장하지 않는 경우

쿠키 없이 세션을 유지하는 방법

  • 쿠키를 사용하지 않고도 세션을 유지할 수 있지만, 이는 덜 일반적이며, 다음과 같은 방식으로 구현됩니다.
  1. URL Rewriting:
    • 세션 ID를 URL에 포함하여 클라이언트와 서버 간에 전달.
    • :
      GET /profile;jsessionid=abcd1234 HTTP/1.1
      
    • 단점:
      • URL이 길어지고 관리가 어려움.
      • 세션 ID가 링크를 통해 외부로 유출될 위험이 있음.
  2. Hidden Field (HTML 폼):
    • 세션 ID를 숨겨진 HTML 입력 필드에 저장하여 폼 데이터와 함께 전송.
    • :
      <form action="/profile" method="POST">
          <input type="hidden" name="jsessionid" value="abcd1234">
          <button type="submit">Submit</button>
      </form>
      
    • 단점:
      • GET 요청에는 사용할 수 없음.
      • 페이지마다 세션 ID를 포함해야 하므로 구현이 복잡.

4. 세션과 쿠키의 공통 허용 여부

웹 브라우저 설정에서 세션과 쿠키가 항상 함께 나오는 이유

  • 쿠키는 세션 ID를 저장하고 전송하는 데 자주 사용되므로, 쿠키가 차단되면 세션도 제대로 동작하지 않을 가능성이 큽니다.
  • 쿠키를 허용하지 않으면 세션 유지가 어려워질 수 있으므로, 브라우저에서 "세션과 쿠키"를 함께 설정 항목으로 묶는 경우가 많습니다.

5. 세션과 쿠키의 차이

  세션(Session) 쿠키(Cookie)
저장 위치 서버 클라이언트(브라우저)
용도 사용자 상태 관리 (예: 로그인) 사용자 데이터 저장 (예: 선호 테마, 언어)
보안성 데이터는 서버에 저장되므로 비교적 안전 클라이언트에 저장되므로 조작/탈취 가능성 있음
데이터 전송 세션 ID만 전송 쿠키 전체 데이터가 요청마다 서버로 전송
유효 기간 서버에서 설정 가능 (일반적으로 세션 유지 동안) 설정된 만료 시간에 따라 유지
상호작용 쿠키를 통해 세션 ID를 전달하는 데 사용 세션 없이도 독립적으로 사용 가능

6. 요약

  • 세션은 서버에서 사용자 상태를 관리하기 위한 데이터이고, 쿠키는 세션 ID를 저장하고 클라이언트와 서버 간에 전송하는 역할을 합니다.
  • 쿠키를 사용하면 세션 ID를 쉽게 관리하고 전송할 수 있으므로, 세션과 쿠키가 자주 함께 사용됩니다.
  • 세션은 반드시 쿠키에 의존하지는 않지만, 쿠키를 사용하지 않으면 구현이 복잡하고 관리가 어려워질 수 있습니다.
    따라서 세션과 쿠키는 **"같이 다니는 것처럼 보인다"**고 느껴질 수 있습니다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] 네트워크 요약  (1) 2025.01.22
[Net] Filter  (1) 2025.01.01
[Net] Token & JWT  (0) 2024.12.29
[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13

Token

📌 Web Application이나 API에서 인증(Authentication)과 인가(Authorization) 과정에서 사용되며 사용자 또는 시스템의 신원과 권한을 증명하고 요청의 유효성을 검증하는 데 사용되는 디지털 문자열이다.

  • 인증(Authentication), 권한 부여(Authorization), 또는 데이터 교환을 위해 클라이언트와 서버 간에 사용되는 작고 안전한 데이터 객체입니다.
  • 로그인 인증이나 사용자 권한 관리를 할 때 토큰을 발급하고, 이를 통해 사용자를 식별하거나 인증 상태를 유지할 수 있습니다.
  • 토큰은 전체 데이터를 포함하지 않는다. 박스가 아니라 키라고 생각해야한다. 말 그대로 다른 클라에 요청할 시 사용가능한 인물인지에 대한 정보만 포함된다. 패킷이 아니다.

  • Token 생성 시 사용자의 고유한 정보를 포함한다.
  • 데이터베이스에 접근하지 않고 Token의 유효성만 검증한다.
  • Token의 단점
    1. Cookie/Session 방식보다 Token 자체의 데이터 용량이 많다.
      • 요청이 많아지면 그만큼 트래픽이 증가한다.
    2. Payload(전송되는 데이터)는 암호화되지 않아서 중요한 데이터를 담을 수 없다.
    3. Token을 탈취당하면 대처하기 어려워 만료 시간(30분)을 설정한다.

 

0. Token을 사용하는 이유

  1. Token은 서버가 아닌 클라이언트에 저장되어 서버의 부담을 덜 수 있다.
  2. Cookie는 웹 브라우저에만 존재하여 모바일 앱 등의 다양한 클라이언트에서 인증을 처리할 수 없다.
  3. Token 방식은 Stateless를 기반으로 하여 확장성이 뛰어나다.
  4. 인증된 사용자임을 확인하기 위한 고유한 서명을 포함하여 위조된 요청인지 확인할 수 있다.

 

1. 토큰의 기본 개념

토큰의 역할

  1. 인증(Authentication):
    • 사용자가 로그인하면 서버는 인증 결과를 기반으로 토큰을 발급합니다.
    • 클라이언트는 이후 요청마다 이 토큰을 사용하여 인증된 사용자임을 증명합니다.
  2. 권한 부여(Authorization):
    • 사용자가 어떤 리소스에 접근할 수 있는 권한이 있는지 확인합니다.
    • 예: "관리자" 권한을 가진 사용자만 특정 API에 접근 가능.
  3. 상태 정보 저장(State):
    • 토큰에 사용자 관련 정보를 포함하여 서버가 상태를 유지하지 않아도 인증 상태를 확인할 수 있습니다.

2. 토큰의 종류

a. 세션 토큰

  • 서버가 상태를 관리하며, 클라이언트는 세션 ID를 사용해 서버에 요청.
  • 예: session_id=abcd1234 쿠키로 저장.

b. JSON Web Token (JWT)

  • 클라이언트 측에서 상태를 관리할 수 있는 자체 포함(Self-Contained) 토큰.
  • 서명(Signature)을 통해 데이터의 변조를 방지.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsIm5hbWUiOiJKb2huIERvZSJ9.s5t0sT5kdcfXb3wNkm2mOiVjHXe

c. OAuth 토큰

  • OAuth2.0 표준에서 사용하는 토큰으로, **액세스 토큰(Access Token)**과 **리프레시 토큰(Refresh Token)**으로 구성.

d. CSRF 토큰

  • CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해 요청마다 고유한 토큰을 생성.

3. JSON Web Token (JWT)의 구조

JWT는 세 가지 부분으로 구성된 문자열이며, 점(.)으로 구분됩니다.

Header.Payload.Signature

Header (헤더):

  • 토큰의 메타정보를 포함.
  • 예: 알고리즘과 토큰 타입.
{
  "alg": "HS256",
  "typ": "JWT"
}

Payload (페이로드):

  • 사용자 정보와 클레임(Claim)을 포함.
  • 예: 사용자 ID, 권한 정보.
{
  "userId": 1,
  "role": "admin"
}

 

Signature (서명):

  • 토큰의 무결성을 검증하기 위한 서명.
  • 비밀키(Secret Key)로 생성.

4. 토큰 기반 인증 흐름

a. 로그인 요청

  • 사용자가 서버에 로그인 요청을 보냅니다.
POST /login HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "username": "john_doe",
  "password": "secure_password"
}

b. 토큰 발급

  • 서버는 사용자를 인증한 후, JWT 또는 세션 토큰을 발급합니다.
HTTP/1.1 200 OK
Content-Type: application/json

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

c. 요청마다 토큰 사용

  • 클라이언트는 이후 요청마다 토큰을 Authorization 헤더에 포함하여 전송합니다.
GET /dashboard HTTP/1.1
Host: example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

d. 서버에서 토큰 검증

  • 서버는 토큰의 서명을 검증하고, 페이로드에 포함된 사용자 정보를 기반으로 요청을 처리합니다.

 

5. 토큰의 장단점

장점

  1. 확장성:
    • 상태를 서버에 저장하지 않으므로, 분산 서버 환경에서도 쉽게 사용 가능.
  2. 자체 포함(Self-Contained):
    • JWT는 페이로드에 필요한 정보를 포함하므로, 서버가 별도의 데이터베이스를 조회할 필요가 줄어듭니다.
  3. 유연성:
    • 토큰은 쿠키, HTTP 헤더, 또는 URL 파라미터로 전달할 수 있습니다.

단점

  1. 보안 취약성:
    • 토큰이 탈취되면 만료 전까지 악용될 수 있습니다.
    • 해결: HTTPS 사용, 짧은 유효 기간, 리프레시 토큰.
  2. 데이터 크기:
    • JWT는 페이로드에 데이터를 포함하므로, 크기가 커질 수 있습니다.
  3. 만료 처리:
    • JWT는 발급 후 변경할 수 없으므로, 토큰이 만료되거나 폐기된 경우 클라이언트에 새로운 토큰을 발급해야 합니다.

6. 토큰과 세션의 차이

  세션 기반 인증 토큰 기반 인증 (JWT)
저장 위치 서버 (세션 ID는 클라이언트에 저장) 클라이언트 (서버에 상태 저장 없음)
확장성 서버가 상태를 관리하므로 확장에 제약 상태를 저장하지 않으므로 확장성 우수
보안성 서버에서 세션 만료나 폐기가 가능 탈취 시 만료 전까지 악용 가능
데이터 크기 세션 ID만 저장 페이로드 포함, 크기가 상대적으로 큼
사용 사례 로그인 상태 유지 (웹 애플리케이션) API 인증, 분산 시스템

7. 토큰 사용 시 보안 고려 사항

  1. HTTPS 사용:
    • 토큰이 네트워크에서 탈취되지 않도록 HTTPS를 통해 전송.
  2. 짧은 유효 기간 설정:
    • 액세스 토큰은 유효 기간을 짧게 설정하고, 만료 시 리프레시 토큰으로 재발급.
  3. 서명 검증:
    • 서버는 토큰의 서명을 반드시 검증하여 변조 여부를 확인.
  4. 탈취 방지:
    • HttpOnly, Secure 속성을 사용해 쿠키로 저장하거나, 브라우저 로컬 저장소에 저장.

8. 요약

  • **토큰(Token)**은 클라이언트와 서버 간 인증 및 권한 부여를 위한 작은 데이터 객체입니다.
  • JWT는 가장 널리 사용되는 토큰 방식으로, 페이로드에 사용자 정보를 포함하여 자체적으로 인증을 수행.
  • 토큰은 분산 시스템과 API 기반 애플리케이션에서 유용하지만, 보안을 강화하기 위해 짧은 유효 기간과 HTTPS 사용 등 추가 조치를 해야 합니다.

 

JWT(JSON Web Token)

📌 인증에 필요한 정보들을 암호화시킨 JSON 형태의 Token을 의미한다. JSON 데이터 포맷을 사용하여 정보를 효율적으로 저장하고 암호화로 서버의 보안성을 높였다.

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

 

JWT 구조

Header

  • 토큰의 타입과 해싱 알고리즘을 정의한다.
  • 예시
{
	"alg": "HS256",
	"typ": "JWT"
}

 

Payload

  • 실제로 인증과 관련된 데이터(Claims)를 담고 있다.
  • Claims의 종류
    • Registered Claims : 미리 정의된 Claims
      • iss(issuer) : 발행자
      • exp(expiration time) : 만료시간
      • sub(subject) : 제목
      • iat(issued At) : 발행 시간
      • jti(JWT ID) : 토큰의 고유 식별자
    • Public Claims : 사용자가 정의할 수 있는 클레임, 공개용 정보 전달 목적
    • Private Claims : 사용자 지정 클레임, 당사자들 간에 정보를 공유하기 위한 목적
  • 예시
{
  "sub": "1234567890",
  "name": "Sparta",
  "exp": 1682563600
}

 

Signature

  • Header와 Payload를 서버의 Secret Key로 서명하여 암호화 한다.
  • 암호화는 Header에서 정의한 알고리즘(alg)을 활용한다.
  • 서명을 통해 서버는 Token이 변조되지 않았음을 확인할 수 있다.
  • 예시
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

 

base64UrlEncode는 값을 URL에서 사용할 수 있도록 +, /를 각각 -, _로 표기한다.
Header와 Payload는 Encoding된 값이기 때문에 복호화 혹은 값을 수정할 수 있지만 Signature는 서버에서 관리하는 값이기 때문에 Secret Key가 유출되지 않는 이상 복호화 할 수 없다.

 

 

JWT 인증

📌 JWT는 Base64로 인코딩되어 쉽게 복호화 할 수 있다. Payload가 그대로 노출되기 때문에 비밀번호나 민감한 정보를 저장하지 않는다.

  1. 클라이언트의 로그인 요청
  2. 로그인에 성공했다면 Header, Payload에 Secret Key를 사용하여 Signature를 만든다.
    • 이후 Base64로 Encoding 한다.
    • 일반적으로 Cookie에 담아 클라이언트에게 JWT를 발급한다.
  3. 발급받은 JWT를 저장 후 서버에 요청할 때 Authorization Header에 JWT를 담아 보낸다.
  4. 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
    • JWT 만료, 위변조 여부를 검사한다.

 

JWT의 유효성 검사

  1. A의 JWT를 B가 탈취
  2. B가 탈취한 JWT를 임의로 수정
  3. B가 수정한 JWT로 Server에 요청
  4. 서버는 Signature를 사용하여 유효성 검사(Signature 불일치)
    • Header, Payload를 서버의 Secret Key값을 이용해 Signature를 다시 만들어 비교한다.
    • 임의로 조작된 데이터를 판별할 수 있다.
JSON Web Token의 목적은 정보 보호가 아닌, 위조 방지에 있다.

 

JWT 장점

  1. Signature로 서버의 보안성이 증가한다.
  2. Token 자체가 필요한 정보(유저 및 검증 정보)들을 모두 가지고 있다.
  3. 서버는 인증 정보와 관련된 별도의 저장소를 사용하지 않는다.
  4. 서버의 수평 확장성(Scale Out)이 높아진다.
  5. Cookie가 없는 다른 환경에서도 인증/인가를 적용할 수 있다.
  6. DB를 조회하지 않아도 된다.
Mobile의 경우 App을 자주 닫거나 백그라운드로 전환하여 Session 방식을 사용하지 않는다.

 

 

JWT 단점

  1. Payload는 암호화 된 것이 아니라 민감한 정보를 다루지 못한다.
  2. Token의 길이가 길어서 트래픽이 증가하면 네트워크에 부하가 증가한다.
  3. 클라이언트 측에서 Token을 관리하기 때문에 탈취당하면 대처하기 어렵다.

 

Access Token, Refresh Token

📌 Token은 클라이언트에서 관리하여 탈취당할 위험성이 높기 때문에 만료 시간 설정이 필요하다. 이 때 발생하는 단점을 극복하기 위해 Access Token과 Refresh Token을 사용한다.

  • Token의 유형
    1. Access Token
      • 사용자 인증 후 서버가 발급하는 유저 정보가 담긴 토큰이다.
      • 유효 기간 동안 API나 리소스에 접근할 때 사용한다.
    2. Refresh Token
      • Access Token은 보안을 위해 짧은 수명을 가진다.
      • Access Token이 만료된 경우 재발급 받기위해 사용한다.
      • 주로 데이터베이스에 유저 정보와 같이 저장한다.
  1. 클라이언트의 로그인 요청
  2. 로그인에 성공했다면 Header, Payload에 Secret Key를 사용하여 Signature를 만든다.
  3. 발급받은 JWT를 저장 후 서버에 요청할 때 Authorization Header에 JWT(Access Token)를 담아 보낸다.
  4. 서버에서 JWT의 유효성 검사를 통해 통과한다면 인증에 성공하여 요청을 처리해준다.
  5. Access Token이 만료 되었다면 Refresh Token 으로 토큰 재발급을 요청한다.
  6. 서버로부터 Access Token을 재발급 받는다.
JWT를 Access Token만을 사용하여 인증한다면 탈취되어 보안에 취약할 수 있다. 유효 시간을 부여하여 문제를 해결하지만 유효 시간이 짧다면 로그인을 자주 해야하기 때문에 Refresh Token을 적용한다.
 
참고하면 좋은 영상

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Filter  (1) 2025.01.01
[Net] Session & Cookie의 관계  (0) 2024.12.31
[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13
[Net] API 설계  (0) 2024.12.12

Cookie

📌 사용자의 웹 브라우저에 저장되는 정보로 사용자의 상태 혹은 세션을 유지하거나 사용자 경험을 개선하기 위해 사용된다. 사용자 정보나 세션 데이터를 클라이언트(브라우저)에 저장하는 기술

  • Cookie는 주로 사용자 세션 관리(로그인, 장바구니, 접속시간)나 광고 트래킹(사용자 행동) 등의 목적으로 사용된다.

  1. HTTP는 Stateless, Connectionless 특성을 가지고 있다.
  2. Client가 재요청시 Server는 이전 요청에 대한 정보를 기억하지 못한다.
  3. 로그인과 같이 상태를 유지해야 하는 경우가 발생한다.
  4. Request에 사용자 정보를 포함하면 해결이 된다.
    • 로그인 후에는 사용자 정보와 관련된 값이 저장되어 있어야한다.
  5. 브라우저를 완전히 종료한 뒤 다시 열어도 사용자 정보가 유지되어야 한다.
서버에 전송하지 않고 브라우저에 단순히 데이터를 저장하고 싶다면 Web Storage(localStorage, sessionStorage)를 사용하면 된다. 하지만 보안에 취약하기 때문에 주민번호와 같은 민감정보를 저장하면 안된다.

Web Storage는 클라이언트의 저장소로, 쿠키와 비교했을 때 서버로 데이터를 자동전송하지 않으며, 클라이언트에서만 데이터를 유지한다는 특징을 가지고 있다.

 

 

  쿠키 (Cookie) Web Storage (localStorage/sessionStorage)
저장 위치 클라이언트(브라우저), HTTP 요청 시 서버로 전송 클라이언트(브라우저), 서버로 자동 전송되지 않음
데이터 전송 HTTP 요청 시 서버로 자동 전송 서버로 전송되지 않음
저장 용량 약 4KB 약 5MB
유효 기간 설정된 만료 시간까지 유지 localStorage는 영구, sessionStorage는 세션 종료 시 삭제
범위 도메인/경로 단위로 설정 가능 localStorage는 모든 탭에서 공유, sessionStorage는 현재 탭에 한정
보안 HttpOnly와 Secure로 보안 강화 가능 자바스크립트를 통해 접근 가능 (XSS 공격에 취약)
주 용도 사용자 상태 유지 (예: 로그인, 인증) 사용자 설정, UI 상태, 임시 데이터 저장
데이터 접근 방식 HTTP 헤더 또는 자바스크립트 API로 접근 자바스크립트 API로 접근
지원 브라우저 모든 브라우저에서 지원 최신 브라우저에서 지원
삭제 방식 쿠키 만료 시간 또는 브라우저 설정에서 삭제 localStorage.clear(), sessionStorage.clear()
  • Cookie 찾아보기
    • 브라우저 개발자도구(F12) → Application → Cookies

 

로그인 성공시 응답

Set-Cookie

  • 로그인시 전달된 ID, Password로 User 테이블 조회하여 일치여부 확인
  • 일치한다면 Set-Cookie를 활용해 Cookie에 사용할 값 저장
    • Cookie는 보안에 취약하다.

 

로그인 이후 요청

요청 헤더 Cookie : 사용자 정보

  • 로그인 이후에는 모든 요청마다 Request Header에 항상 Cookie 값을 담아서 요청한다.
    • 클라이언트 → 서버 방향의 요청
    • 네트워크 트래픽이 추가적으로 발생된다.
    • 최소한의 정보만 사용해야한다.
  • Cookie에 담겨있는 값으로 인증/인가 를 진행한다.

 

Cookie Header

📌 클라이언트(브라우저)가 서버에 HTTP 요청을 보낼 때, 클라이언트에 저장된 쿠키를 함께 전송하는 HTTP 요청 헤더입니다.

  • 서버에서는 HTTP 응답 헤더에 Set-Cookie 속성을 사용해 생성하고 설정할 수 있다
  • Cookie는 서버에서 생성되어 클라이언트에 전달, 저장된다.

 

Cookie Header

  1. Set-Cookie
    • Server에서 Client로 Cookie 전달(Response Header)
  2. Cookie
    • Client가 Cookie를 저장하고 HTTP 요청시 Server로 전달(Request Header)

Response 알아보기

set-cookie: 
sessionId=abcd; 
expires=Sat, 11-Dec-2024 00:00:00 GMT;
path=/; 
domain=spartacodingclub.kr;
Secure
  • Cookie의 생명주기
    1. 세션 Cookie
      • 만료 날짜를 생략하면 브라우저 완전 종료시 까지만 유지된다.(Default)
        • expires, max-age 가 생략된 경우
      • 브라우저를 완전 종료 후 다시 페이지를 방문했을 때 다시 로그인을 해야한다.
    2. 영속 Cookie
      • 만료 날짜를 입력하면 해당 날짜까지 유지한다.
        • expires=Sat, 11-Dec-2024 00:00:00 GMT;
          • 해당 만료일이 도래하면 쿠키가 삭제된다.
        • max-age=3600 (second, 3600초는 한시간. 60 * 60)
          • 0이 되거나 음수를 지정하면 쿠키가 삭제된다.
  • Cookie의 도메인
    • 쿠키가 아무 사이트에서나 생기고 동작하면 안된다!
      • 필요없는 값 전송, 트래픽 문제 등이 발생한다.
    • domain=spartacodingclub.kr
      • domain=spartacodingclub.kr를 지정하여 쿠키를 저장한다.
      • dev.spartacodingclub.kr와 같은 서브 도메인에서도 쿠키에 접근한다.
    • domain을 생략하면 현재 문서 기준 도메인만 적용한다.
  • Cookie의 경로
    • 1차적으로 도메인으로 필터링 후 Path가 적용된다.
    • 일반적으로 path=/ 루트(전체)로 지정한다.
    • 위 경로를 포함한 하위 경로 페이지만 쿠키에 접근한다.
      • path=/api 지정
        • path=/api/example 가능
        • path=/example 불가능
  • Cookie 보안
    1. Secure
      • 기본적으로 Cookie는 http, https 구분하지 않고 전송한다.
      • Secure를 적용하면 https인 경우에만 전송한다. s = Secure
    2. HttpOnly
      • XSS(Cross-site Scripting) 공격을 방지한다.
        • 악성 스크립트를 웹 페이지에 삽입하여 다른 사용자의 브라우저에서 실행되도록 하는 공격
      • 자바스크립트에서 Cookie 접근을 못하도록 막는다.
      • HTTP 요청시 사용한다.
    3. SameSite
      • 비교적 최신 기능이라 브라우저 지원여부를 확인 해야한다.
      • CSRF(Cross-Site Request Forgery) 공격을 방지한다.
        • 사용자가 의도하지 않은 상태에서 특정 요청을 서버에 전송하게 하여 사용자 계정에서 원치 않는 행동을 하게 만든다.
      • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

 

 

Cookie로 로그인 상태 유지하기

 

  • 한번 로그인에 성공하면 HTTP Response에 쿠키를 담아서 브라우저에 전달한다.
  • 브라우저는 요청마다 Cookie를 함께 전송한다.
  • 보안상의 문제로 name=원욱이 아닌 userId=1과 같은 index 정보를 저장한다.
    • 이것 또한 보안문제가 있다.
  • 요구사항에 맞추어 세션 Cookie를 사용할지 영속 Cookie를 사용할지 결정한다.

  • 코드예시
    • 예시를 위해 ViewTemplate(Thymeleaf)을 사용하는 경우를 가정(SSR)
더보기

User 클래스

@Getter
public class User {
    // 식별자
    private Long id;
    // 이름
    private String name;
    // 나이
    private Integer age;
    // 로그인 ID
    private String userName;
    // 비밀번호
    private String password;

    public User(Long id, String name, Integer age, String userName, String password) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.userName = userName;
        this.password = password;
    }
}
  • User 클래스 설계

로그인 요청 DTO

// 필드 전체를 매개변수로 가진 생성자가 있어야 @ModelAttribute가 동작한다.
@Getter
@AllArgsConstructor
public class LoginRequestDto {
	// 사용자가 입력한 아이디
	@NotBlank	
	private final String userName;
	// 사용자가 입력한 비밀번호
	@NotNull
	private final String password;
}
  • 일반적으로 DTO는 클라이언트의 요청혹은 서버의 응답이기 때문에 변경되면 안된다.
    • final을 사용하여 불변 객체로 관리한다.
    • Java17 버전에 나온 record를 사용할 수 있다.

로그인 응답 DTO

@Getter
public class LoginResponseDto {
    private final Long id;
    // 이외 응답에 필요한 데이터들을 필드로 구성하면 된다.
    // 필요한 생성자
    public LoginResponseDto(Long id) {
        this.id = id;
    }
}

 

유저 조회 응답 DTO

@Getter
public class UserResponseDto {
		// 유저 식별자
    private final Long id;
    // 유저 이름
    private final String name;

    public UserResponseDto(Long id, String name) {
        this.id = id;
        this.name = name;
    }
}

 

 

HomeController

@Controller
@RequiredArgsConstructor
public class HomeController {

    private final UserService userService;

    @GetMapping("/home")
    public String home(
            // @CookieValue(required = true) 로 필수값(default) 설정
            // required = false 이면 필수값 아님.
            @CookieValue(name = "userId", required = false) Long userId, // String->Long 자동 타입컨버팅
            Model model
    ) {

        // 쿠키에 값이 없으면 로그인 페이지로 이동 -> 로그인 X
        if(userId == null) {
            return "login";
        }

        // 실제 DB에 데이터 조회 후 결과가 없으면 로그인 페이지로 이동 -> 일치하는 회원정보 X
        UserResponseDto loginUser = userService.findById(userId);

        if(loginUser == null) {
            return "login";
        }

        // 정상적으로 로그인 된 사람이라면 View에서 사용할 데이터를 model 객체에 데이터 임시 저장
        model.addAttribute("loginUser", loginUser);
        // home 화면으로 이동
        return "home";
    }
}

View에서는 model 객체에 담겨있는 loginUser 를 활용하여 변수로 사용할 수 있다.

 

UserController

@Controller
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @PostMapping("/login")
    public String login(
            @Valid @ModelAttribute LoginRequestDto request,
            HttpServletResponse response // 쿠키값 세팅에 필요
    ) {
        // 로그인 유저 조회
        LoginResponseDto responseDto = userService.login(request.getUserName(), request.getPassword());

        if (responseDto.getId() == null) {
            // 로그인 실패 예외처리
            return "login";
        }

        // 로그인 성공 처리
        // 쿠키 생성, Value는 문자열로 변환하여야 한다.
        Cookie cookie = new Cookie("userId", String.valueOf(responseDto.getId()));

        // 쿠키에 값 세팅 (expire 시간을 주지 않으면 세션쿠키가 됨, 브라우저 종료시 로그아웃)
        // Response Set-Cookie: userId=1 형태로 전달된다.
        response.addCookie(cookie);
        
        // home 페이지로 리다이렉트
        return "redirect:/home";
    }

    @PostMapping("/logout")
    public String logout(
            HttpServletResponse response
    ) {
        Cookie cookie = new Cookie("userId", null);
        // 0초로 쿠키를 세팅하여 사라지게 만듬
        cookie.setMaxAge(0);
        response.addCookie(cookie);

        // home 페이지로 리다이렉트
        return "redirect:/home";
    }

}
  1. 로그인 기능
    • 로그인에 성공하면 Cookie를 생성하고 HttpServletResponse 객체에 담는다.
      • Cookie 이름(Key)은 userId , 값(Value)은 회원 index 값을 담아둔다.
      • Set-Cookie: userId=1
    • 만료 시간을 지정하지 않으면 세션 쿠키로 만들어진다.
      • 브라우저 종료 전까지 userId 가 모든 요청 헤더의 Cookie에 담겨서 전달된다.
  2. 로그아웃 기능
    • 새로운 Cookie를 userId = null로 생성한다.
    • setMaxAge(0) 설정으로 만료시킨다.
    • 응답에 만료된 쿠키를 담아 보낸다.

UserService

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    public LoginResponseDto login(String userName, String password) {
        // 입력받은 userName, password와 일치하는 Database 조회
        Long index = userRepository.findIdByUserNameAndPassword(userName, password);

        return new LoginResponseDto(index);
    }

    public UserResponseDto findById(Long id) {

        return userRepository.findById(id);
    }
}

 

UserRepository

@Repository
public class UserRepository {

    private static final User USER1 = new User(1L, "wonuk", 100, "wonuk", "1234");
    private static final User USER2 = new User(2L, "wonuk2", 200, "wonuk2", "2345");
    private static final List<User> USERS = Arrays.asList(USER1, USER2);

    public Long findIdByUserNameAndPassword(String userName, String password) {
        return USERS.stream()
                .filter(user -> user.getUserName().equals(userName) && user.getPassword().equals(password))
                .map(User::getId)
                .findFirst()
                .orElse(null);
    }

    public UserResponseDto findById(Long id) {
        return USERS.stream()
                .filter(user -> Objects.equals(user.getId(), id))
                .map(user -> new UserResponseDto(user.getId(), user.getName()))
                .findFirst()
                .orElse(null);
    }
}

실제 Database와 연동하지 않고, 상수로 미리 만든 User를 사용한다.

 

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<h2>Login</h2>
<form th:action="@{/login}" method="post">
    <div>
        <label for="userName">Username:</label>
        <input type="text" id="userName" name="userName" required>
    </div>
    <div>
        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required>
    </div>
    <button type="submit">Login</button>
</form>

</body>
</html>

 

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Home</title>
</head>
<body>
<h1>Welcome Home!</h1>

<p th:text="'안녕하세요, ' + ${loginUser.name} + '님!'">Hello, User!</p>

<!-- 로그아웃 버튼 -->
<form th:action="@{/logout}" method="post" style="margin-top: 10px;">
    <button type="submit">Logout</button>
</form>

</body>
</html>

 

 

브라우저 테스트

http://localhost:8080/home

  • HomeController 호출
  • Cookie에 값이 없는 상태로 login 페이지가 반환된다.

DB에 저장된 userName과 password로 로그인

 

  • 로그인이 실패하면 login 페이지로 이동한다.
  • 로그인이 성공하면 home 페이지로 리다이렉트
  • 리 다이렉트되어 GET + /home 호출
  • Cookie에 저장된 user 식별자 값으로 DB 조회
  • 조회된 User를 Model에 추가
  • home 페이지에서 Model을 참조하여 화면 출력

 

 

Cookie 문제점

📌 Cookie는 보안에 취약하여 userId=1 형태의 방식으로 로그인을 구현하지 않는다.

  • = 쿠키에 민감한 정보를 직접 저장하거나 이를 기반으로 인증 로직을 구현하지 않는다
  • userId=1은 데이터를 숨기지 않고 직접 대놓고 저장하는 방식

 

Cookie 문제점

쿠키 값은 임의로 변경할 수 있다.

  • Client가 임의로 쿠키의 값을 변경하면 서버는 다른 유저로 인식한다.
  • userId = 임의로 수정

  • 브라우저 개발자도구(F12) → Application → Cookies → 값 수정 가능
  • 실제로는 암호화되어 저장되어있는 Value들을 볼 수 있다!

Cookie에 저장된 Data는 탈취되기 쉽다.

  • userId = 주민번호, userId = 인덱스 값
  • 쿠키는 네트워크 전송 구간에서 탈취될 확률이 매우 높다.
    • HTTPS를 사용하는 이유 중 하나에 속한다.
    • 민감한 정보를 저장하면 안된다.
  • 한번 탈취된 정보는 변경이 없다면 반영구적으로 사용할 수 있다.

 

보안 대처방법

  1. 쿠키에 중요한값을 저장하지 않는다.
  2. 사용자 별로 일반 유저나 해커들이 알아보지 못하는 값을 노출한다.
    • 일반적으로 암호화된 Token을 쿠키에 저장한다.
    • 서버에서 암호화된 Token과 사용자를 매핑해서 인식한다.
    • Token은 서버에서 관리한다.
  3. 토큰은 해커가 임의의 값을 넣어도 동작하지 않도록 만들어야 한다.
  4. 해커가 토큰을 탈취해도 사용할 수 없도록 토큰 만료시간을 짧게 설정한다.
  5. 탈취가 의심되는 경우 해당 토큰을 강제로 만료시키면 된다.
    • 접속기기 혹은 IP가 다른 경우 등

 

 

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Session & Cookie의 관계  (0) 2024.12.31
[Net] Token & JWT  (0) 2024.12.29
[Net] MVC 패턴  (0) 2024.12.13
[Net] API 설계  (0) 2024.12.12
[Net] Rendering  (1) 2024.12.05

Template Engine

📌 동적인 웹 페이지를 생성하기 위해 사용되는 도구이며 템플릿을 기반으로 정적인 부분과 동적인 데이터를 결합하여 HTML, XML 등 의 문서를 생성하는 역할을 수행한다.

  •  우리가 흔히 말하는 UI(User Interface)를 만들며, SSR(Server Side Rendering)에 사용된다.
  • 정적 출력은 [안내 메시지]와 같은 모든 사용자에게 동일하게 보이는 데이터를 말하고 동적 데이터는 [사용자 이름]과 같은 사용자, 상황마다 다른 결과를 표현하는 데이터다.
  • 아래와 같이 서버에서 보내는 데이터를 html쪽에서 정의하는 방식으로 접근이 편리하게 만들어준다.
    <!-- 정적 출력 -->
    <h1>안녕하세요, 방문해주셔서 감사합니다!</h1>

    <!-- 동적 출력 -->
    <p>안녕하세요, <span th:text="${name}">이름</span>님!</p>


	[실제 출력]

    <!-- 정적 출력 -->
    <h1>안녕하세요, 방문해주셔서 감사합니다!</h1>

    <!-- 동적 출력 -->
    <p>안녕하세요, <span>철수</span>님!</p>

  • 템플릿 엔진이 나온 이유
    • 자바 코드로 HTML을 만들어 내는 것이 아닌 HTML 문서에 동적으로 변경해야 하는 부분만 자바 코드를 넣을 수 있다면 더 편리하다.
  • 대표적인 템플릿 엔진
    1. Thymeleaf
      • Spring과 통합이 잘 되어있다.
      • 다양한 기능을 포함하고 있다.
    2. JSP(Java Server Pages)
      • 예전엔 많이 사용했으나, 현재 안 쓰는 추세
    3. FreeMarker
    4. Velocity
    5. Mustache

 

MVC 패턴 개요

📌 Servlet이나 JSP만으로 비지니스 로직과 View Rendering 까지 모두 처리하면 너무 많은 역할을 하게 되고 유지보수가 굉장히 어려워져서(책임이 너무 많음) 고안된 패턴이다. Web Application은 일반적으로 MVC(Model View Controller) 패턴을 사용한다.

  • Servlet 문제점
    • 화면을 그리는 View 영역과 비지니스 로직이 Servlet 하나에 모두 섞여있다.
    • 책임을 너무 많이 가지고 있다.

Servlet 동작 순서

  1. 사용자가 Client(브라우저)를 통해 서버에 HTTP Request 즉, API 요청을 한다.
  2. 요청을 받은 Servlet 컨테이너는 HttpServletRequest, HttpServletResponse객체를 생성한다.
  3. 설정된 정보(URL, HTTP Method)를 통해 어떠한 Servlet에 대한 요청인지 찾는다.
  4. 해당 Servlet에서 service 메서드를 호출한 뒤 브라우저의 요청 Method에 따라 doGet() 혹은doPost() 등의 메서드를 호출한다.
  5. 서버에서 응답을 생성한 뒤 HttpServletResponse객체에 응답을 담아 Client(브라우저)에 반환한다.
  6. 응답이 완료되면 생성한 HttpServletRequest, HttpServletResponse객체를 소멸한다.
  • JSP
    • Servlet 코드에서 HTML을 만드는 부분인 View가 분리되었다.
    • 하지만 여전히 문제가 있는데, Servlet만 사용할 경우 View를 위한 코드와 비지니스 로직을 처리하는 코드가 Servlet에 모두 존재하며 유지보수가 어려워진다.
    • JSP를 사용하여 View를 분리하였지만 비지니스 로직의 일부가 JSP파일안에 존재한다. 여전히 책임이 많아 유지보수가 어렵다.

 

MVC 패턴

📌 하나의 Servlet이나 JSP로 처리하던 것들을 Model, View, Controller 영역으로 나눈것이다.

 

  • 핵심 내용
    • View가 분리된 이유의 핵심은 변경이다.
    • 기획이 변하지 않는 이상 비지니스 로직과 View의 수정 원인은 별개로 발생한다.
      • 화면 구성에 수정이 발생하면 View만 변경
      • 요구사항에 수정이 발생하는 경우 비지니스 로직 변경
    • 즉, 서로 연관이 없는 코드끼리 함께 존재할 필요가 없다. 완전히 분리하자

 

MVC 패턴 구조

  • Controller
    • 예시 코드에서 Servlet에 해당하는 영역이다.
    1. HTTP Request를 전달받아 파라미터를 검증한다.
    2. 비지니스 로직을 실행한다.
      • 비지니스 로직을 Controller에 포함하게되면 Controller가 너무 많은 역할을 담당하게 되어 일반적으로 Service Layer를 별도로 만들어서 처리한다.
      • Database와 상호작용 하는 Layer를 따로 구분하여 Repository Layer를 추가로 구성한다.
      • 위와 관련된 자세한 내용인 Layered Architecture는 다음 강의에서 알아보자.
      • Controller도 비지니스 로직을 포함할 수 있지만 일반적으로 Service Layer를 호출하는 역할을 담당한다.
    3. View에 전달할 결과를 조회하여 Model 객체에 임시로 저장한다.
  • Model
    1. View에 출력할 Data를 저장하는 객체이다.
    2. View는 비지니스 로직이나 Data 접근을 몰라도 되고 View Rendering에만 집중하면 된다.(책임 분리)
  • View
    • 예시 코드에서 JSP에 해당하는 영역이다.
    1. Model 객체에 담겨져 있는 Data를 사용하여 화면을 Rendering 한다.

 

 

MVC 패턴의 문제점

📌 MVC 패턴을 적용 후 View의 역할은 필요한 데이터를 Model 에서 참조하여 화면을 그리는 역할만 수행하면 된다. 하지만 Controller에 해당하는 부분은 여전히 문제를 가지고 있다.

  • 문제점
    1. dispatcher.forward(request, response) View로 이동하는 forward( 서버가 하나의 요청을 다른 리소스(예: JSP, 서블릿)로 전달 )가 항상 중복 호출된다.
    2. String path= “/WEB-INF/views/new-form.jsp” View의 path를 입력(중복 작업)한다.
      1. jsp 파일의 경로 혹은 이름이 바뀌면 해당 코드가 변경되어야 한다.
      2. JSP 이외의 확장자를 사용하려면 전체가 변경되어야 한다.
    3. 위의 내용을 설명하면, 클라에서 서버에 계속해서 같은 내용을 반복 요청한다는 것, 그런데 그걸 받는 컨트롤러가 하나에만 배치되면 되는데 다 각각 배치된다는 것.. (카페 알바에게 아메리카노 3잔시켰는데 다른 주문도 많은데 알바 3명이서 1개씩 만들고 있다...)
    4. HttpServletResponse 객체를 사용하는 경우가 적다. (JSP에서 모두 해결하기 때문)
      1. HttpServletRequest와 HttpServletResponse는 Test 코드를 작성하기도 매우 힘들다.
    5. 공통 기능이 추가될수록 Controller에서 처리해야 하는 부분들이 많아진다.
  • 공통 기능 처리
    • 모든 컨트롤러에서 공통으로 적용되는 기능을 뜻한다.
    ex) Log 출력, 인증, 인가 등

  • 공통 기능을 Method로 분리하여 각각의 컨트롤러에서 사용하면 되는것 아닌가요? 라고 생각이 가능하지만, 공통 기능으로 만들어놓은 Method 또한 항상 중복적으로 호출이 필요합니다. 또한, 사람인 개발자가 작업하다보면 Method를 호출하는 일을 깜빡 할수도 있고 Method가 많아지면 많아질수록 Controller의 책임이 점점 커진다. 이를 위해 아래의 대안이 나왔다.

 

프론트 컨트롤러 패턴

📌 Servlet(Controller)이 호출되기 전에 공통 기능을 하나의 Servlet에서 처리해주는 패턴이다. 프론트 컨트롤러(Servlet) 하나에 모든 클라이언트측 요청이 들어온다.

  • 프론트 컨트롤러의 역할
    1. 모든 요청을 하나의 프론트 컨트롤러가 받는다.
    2. 공통 기능을 처리한다.
    3. 요청을 처리할 수 있는 Controller를 찾아서 호출한다.(Controller Mapping)
    4. 프론트 컨트롤러를 제외한 나머지 컨트롤러는 Servlet을 사용하지 않아도 된다.
      • 일반 Controller들은 HttpServlet을 상속( HTTP 프로토콜 기반의 요청과 응답을 처리하기 위해 제공되는 클래스 )받거나, @WebServlet(URL 매핑 여기서는 url과 servlet과의 매핑을 말한다.)을 사용하지 않아도 된다. = 프론트 컨트롤러가 처리함
      • @WebServlet의 설명이 이해가 안될 수도 있는데, url은 말 그대로 주소 식별자다. url에 보내는 요청을 보고 어느 servlet에서 처리를 할지 정하고 해당 servlet에 배치(매핑)하는 과정은 완전별개의 문제이다.
  • 프론트 컨트롤러 의문점
    • 프론트 컨트롤러를 사용하면 모든 컨트롤러에서 같은 형태의 응답을 해야하는가?

    • 위 그림처럼 공통 처리 로직에 모든 컨트롤러가 연결되기 위해서는 모든 컨트롤러가 return 하는 결과의 형태가 동일해야 한다.
    • 하지만, Controller 마다 로직이나 응답해야하는 결과는 당연히 다를테고 응답을 동일하게 맞추려고 한다면 해당 애플리케이션은 확장성, 유지보수성을 잃는다.
    • 공통 로직에서 응답별로 퍼즐을 다시 하나하나 처리할 수 있으나 공통 부분의 책임이 너무 커지게된다. 또한, 컨트롤러에서 반환되는 결과가 달라지면 공통처리 부분의 변경또한 불가피하다.
    • 그래서 아래의 대안이 또 나왔다.

 

어댑터 패턴

📌 어댑터 패턴호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록 중간에서 변환을 도와주는 디자인 패턴입니다. 주로, 이미 존재하는 코드와 새로운 코드 사이의 호환성 문제를 해결하는 데 사용됩니다.

  • 컨트롤러들은 동일한 인터페이스를 구현하도록 하고 해당 인터페이스와 공통 로직 사이에 어댑터를 두어 유연하게 만든다. 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴이다.
  • 이해가 잘 안된다면 아래의 접은글을 참고
더보기
 

비유: 요리사, 레시피, 그리고 주방

  1. 요리사(각 컨트롤러)
    • 요리사는 특정 요리(기능)를 책임지고 있습니다.
    • 하지만 요리사는 "자신만의 레시피(방법)"만 알고, 다른 요리사들이 어떤 레시피를 사용하는지 알지 못할 수도 있습니다.
  2. 레시피(인터페이스 또는 요청 처리)
    • 레시피는 요리사가 따라야 하는 공통된 규칙(인터페이스)입니다.
    • 예를 들어, 레시피에 따라 어떤 순서로 재료를 조합할지 정의됩니다.
    • 모든 요리사가 이 레시피를 준수해야 주방이 동작을 관리하기 쉬워집니다.
  3. 주방(공통 로직 또는 프론트 컨트롤러)
    • 주방은 요리사들이 만든 다양한 레시피를 필요한 시점에 호출하고, 손님(사용자)에게 제공할 음식을 최종적으로 내놓습니다.
    • 주방은 모든 요리를 직접 만들지 않고, 요리사들에게 필요한 일을 분담시킵니다.

어댑터 패턴의 맥락에서

주방에서 레시피(인터페이스)를 공유하여 요리사들이 협업 가능하게 만드는 구조는 어댑터 패턴과 비슷합니다.

  • 주방(공통 처리 로직)과 요리사(개별 로직)가 서로 다른 방식을 사용하고 있다면, 어댑터(중간 번역기)를 통해 조율할 수 있습니다.

프론트 컨트롤러를 요리사와 주방에 비유하면

  1. 요리사 (각 컨트롤러)
    • @Controller를 사용한 일반 컨트롤러.
    • HTTP 요청이 들어오면, 요리사(컨트롤러)는 특정 요리를 준비하는 역할을 수행.
    • 클라이언트 요청에 따라 요리사는 자신의 비즈니스 로직에만 집중.
  2. 레시피 (인터페이스)
    • 요리사가 동작할 때 따라야 하는 규칙.
    • 예를 들어, Spring MVC에서는 @RequestMapping 또는 @GetMapping 등의 애너테이션이 이런 역할을 함.
  3. 주방 (프론트 컨트롤러)
    • Spring의 DispatcherServlet 같은 역할.
    • 모든 요청이 주방으로 들어오고, 주방은 적절한 요리사(컨트롤러)를 찾아 요청을 전달.
    • 공통적인 작업(예: 인증, 로깅, 예외 처리 등)을 주방에서 처리한 뒤 요리사에게 넘김.

  1. 컨트롤러(Handler)는 비지니스 로직을 처리하고 알맞은 결과를 반환한다.
  2. 어댑터는 공통 로직과 컨트롤러(Handler)가 자연스럽게 연결되도록 한다.
  3. 프론트 컨트롤러는 공통으로 처리되는 로직을 수행한다.
  • 어댑터 패턴 장점
    • 프론트 컨트롤러, 어댑터, 핸들러 모두 각자의 역할만 수행한다. (책임 분리)
    • 새로운 컨트롤러(Handler)가 추가되어도 컨트롤러와 어댑터만 추가한다면 공통 로직의 변경이 발생하지 않는다.

 

요약

  1. Servlet 사용
    • 비지니스 로직을 처리하는 코드와 화면을 그리는 View 코드가 함께 존재하는 문제
  2. JSP 사용
    • View 에 해당하는 코드를 분리하였지만, 여전히 비지니스 로직을 JSP에 포함하는 문제
  3. MVC 패턴 사용
    • 공통 로직을 처리하는것에 코드가 중복되는 문제
  4. 프론트 컨트롤러 패턴 사용
    • 공통 로직을 하나의 입구에서 처리하기 위해서 프론트 컨트롤러 패턴 적용
    • 각각의 핸들러 호출 후 응답을 프론트 컨트롤러에 맞게 변형시켜야 하는 문제
  5. Spring MVC 사용
    • 프론트 컨트롤러 패턴, 어댑터 패턴이 모두 적용된 현재
    • 우리가 사용하는 Spring을 이용한 Web Application 개발 방식에 사용됨
    • Spring은 MVC 패턴에 프론트 컨트롤러 패턴, 어댑터 패턴이 적용되어 있다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Token & JWT  (0) 2024.12.29
[Net] Cookie  (1) 2024.12.28
[Net] API 설계  (0) 2024.12.12
[Net] Rendering  (1) 2024.12.05
[Net] Servlet  (1) 2024.12.04
요구사항 API URI 설계
  회원 목록 조회
• 회원 조회
• 회원 등록
• 회원 수정
• 회원 삭제
  회원 목록 조회 /read-member-list
• 회원 조회 /read-member-by-id
• 회원 등록 /create-member
• 회원 수정 /update-member
• 회원 삭제 /delete-member

 

단적으로 위의 설계는 틀린 방식이다.

가장 중요한 것은 리소스 식별

 

API URI 고민

URI(Uniform Resource Identier)

 

• 리소스의 의미는 뭘까?

  • 회원을 등록하고 수정하고 조회하는게 리소스가 아니다!
  • 예) 미네랄을 캐라 -> 미네랄이 리소스
  • 회원이라는 개념 자체가 바로 리소스다.

• 리소스를 어떻게 식별하는게 좋을까?

  • 회원을 등록하고 수정하고 조회하는 것을 모두 배제
  • 회원이라는 리소스만 식별하면 된다. -> 회원 리소스를 URI에 매핑
요구사항 API URI 설계
  회원 목록 조회
• 회원 조회
• 회원 등록
• 회원 수정
• 회원 삭제
  회원 목록 조회 /members
• 회원 조회 /members/{id}
• 회원 등록 /members/{id}
• 회원 수정 /members/{id}
• 회원 삭제 /members/{id} 

참고: 계층 구조상 상위를 컬렉션으로 보고 복수단어 사용 권장(member -> members)

 

 

리소스와 행위 분리

가장 중요한 것은 리소스를 식별하는 것

 

• URI는 리소스만 식별!

• 리소스와 해당 리소스를 대상으로 하는 행위을 분리

  • 리소스: 회원
  • 행위: 조회, 등록, 삭제, 변경

• 리소스는 명사, 행위는 동사 (미네랄을 캐라)

• 행위(메서드)는 어떻게 구분?

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Cookie  (1) 2024.12.28
[Net] MVC 패턴  (0) 2024.12.13
[Net] Rendering  (1) 2024.12.05
[Net] Servlet  (1) 2024.12.04
[Net] Web Application  (1) 2024.12.03

Rendering

📌 웹 애플리케이션에서 콘텐츠를 화면에 표시하는 과정을 의미합니다. 이 과정은 주로 웹 브라우저에서 일어나며, HTML, CSS, JavaScript 코드가 결합되어 최종적으로 사용자가 볼 수 있는 페이지로 변환됩니다.

 

[1]  렌더링의 주요 과정

  1. HTML 파싱 (Parsing):
    • 브라우저가 웹 페이지를 로드하면 먼저 HTML 파일을 받아들입니다. 이 HTML 파일은 **DOM(Document Object Model)**으로 변환됩니다. DOM은 웹 페이지의 구조를 트리 형태로 나타내는 객체입니다.
  2. CSS 파싱:
    • HTML이 파싱되면서 CSS 파일도 함께 로드됩니다. CSS 파일은 페이지의 스타일을 정의하며, 이 스타일은 HTML 요소에 적용되어 화면에 표시됩니다. CSS는 **CSSOM(CSS Object Model)**이라는 객체 모델로 변환됩니다.
  3. 렌더 트리 생성:
    • DOM과 CSSOM이 결합되어 **렌더 트리(Render Tree)**가 만들어집니다. 렌더 트리는 화면에 실제로 표시할 요소들만 포함됩니다. 예를 들어, display: none이 설정된 요소는 렌더 트리에 포함되지 않습니다.
  4. 레이아웃(Layout):
    • 렌더 트리가 만들어지면, 각 요소의 정확한 위치와 크기를 계산하는 레이아웃 단계가 진행됩니다. 이 과정에서 각 요소가 페이지 상에서 차지할 공간을 결정합니다.
  5. 페인팅(Painting):
    • 레이아웃이 완료되면 각 요소를 실제 화면에 그리는 페인팅 단계가 시작됩니다. 이 단계에서는 색상, 텍스트, 이미지 등 시각적 요소가 화면에 그려집니다.
  6. 합성(Compositing):
    • 페이지가 여러 레이어로 구성된 경우, 각 레이어가 화면에 어떻게 합성될지를 결정하는 단계입니다. 예를 들어, 애니메이션이나 CSS 트랜지션을 포함한 요소들이 각기 다른 레이어에 배치될 수 있습니다.

[2]  렌더링의 종류

  1. 서버 사이드 렌더링 (SSR, Server-Side Rendering):
    • 서버에서 HTML을 렌더링하고 클라이언트에게 전달하는 방식입니다. 클라이언트는 서버에서 이미 완성된 HTML을 받게 되므로 페이지가 더 빨리 렌더링됩니다. 검색 엔진 최적화(SEO)에도 유리합니다.
  2. 클라이언트 사이드 렌더링 (CSR, Client-Side Rendering):
    • JavaScript가 클라이언트에서 HTML을 렌더링하는 방식입니다. 초기 로딩 시 서버에서 최소한의 HTML만 제공하고, 클라이언트에서 JavaScript가 실행되어 동적으로 콘텐츠를 로드하고 표시합니다.
  3. 하이브리드 렌더링:
    • SSR과 CSR을 결합한 방식으로, 초기 페이지를 서버에서 렌더링하고, 이후 동적인 콘텐츠는 클라이언트에서 렌더링하는 방식입니다. React의 Hydration 기법이 대표적인 예입니다.

[3]  렌더링 성능 최적화

  1. Lazy Loading (지연 로딩):
    • 페이지의 필요한 부분만 먼저 렌더링하고, 나머지 부분은 사용자가 필요할 때 로드하는 방식입니다. 이는 초기 로딩 시간을 줄이는 데 유용합니다.
  2. Critical CSS:
    • 페이지 렌더링에 필요한 최소한의 CSS만 먼저 로드하고, 나머지는 비동기적으로 로드하는 방식입니다. 이렇게 하면 페이지 렌더링 속도가 빨라집니다.
  3. Render Blocking 리소스 최적화:
    • JavaScript나 CSS가 페이지 렌더링을 차단하지 않도록 비동기 로딩하거나 async 또는 defer 속성을 활용하는 방식입니다.
  4. Request Animation Frame (RAF):
    • JavaScript 애니메이션을 최적화하는 기법으로, 화면 리프레시 주기와 맞추어 애니메이션을 실행하여 성능을 최적화합니다.

[4]  렌더링과 관련된 주요 용어

  • Reflow: DOM 요소의 크기나 위치가 변경될 때 레이아웃을 다시 계산하는 과정입니다. 이는 성능에 큰 영향을 줄 수 있습니다.
  • Repaint: 요소의 스타일이 변경되어 화면을 다시 그리는 과정입니다. 스타일만 변경되었을 때는 레이아웃을 재계산하지 않고 화면을 다시 그리기만 합니다.

[5]  렌더링 과정에서의 최적화

  • 렌더링 차단 리소스 최소화: CSS나 JavaScript와 같은 리소스가 렌더링을 차단하지 않도록 최적화합니다.
  • 이미지 최적화: 이미지를 압축하거나 적절한 포맷을 사용하여 로딩 시간을 줄이고 렌더링 성능을 향상시킵니다.
  • DOM 최소화: DOM의 크기를 최소화하고, 불필요한 DOM 업데이트를 피하는 것이 렌더링 성능에 도움이 됩니다.

 

 

SSR(Server Side Rendering)

📌 웹 애플리케이션에서 서버가 HTML을 생성하여 클라이언트에 전달하는 방식입니다. 즉, 클라이언트가 웹 페이지를 요청하면, 서버에서 HTML을 미리 렌더링하고 완성된 페이지를 클라이언트에 전달하는 방식입니다.

 

  1. 서버(WAS)에 HTML을 요청한다.
  2. 서버(WAS)에서 로직을 거친 후 DB를 조회한다.
  3. 조회 결과를 기반으로 HTML을 동적으로 생성한다.
  4. 생성된 HTML을 응답한다.

 

[1]  SSR의 개념

  • **서버 사이드 렌더링 (SSR)**은 클라이언트가 웹 페이지를 요청할 때, 서버에서 HTML을 미리 렌더링하여 클라이언트에게 전달하는 방식입니다.
  • 클라이언트는 서버에서 전달받은 완성된 HTML을 바로 표시하며, 이후 JavaScript가 추가적으로 실행되어 페이지를 동적으로 업데이트하는 방식으로 동작합니다.

[2]  SSR의 작동 원리

  1. 클라이언트 요청: 사용자가 웹 브라우저에서 페이지를 요청합니다.
  2. 서버 렌더링: 서버는 요청된 URL에 해당하는 페이지를 서버 측에서 미리 렌더링하여 완성된 HTML을 생성합니다.
  3. HTML 전달: 생성된 HTML 페이지를 클라이언트로 전달합니다.
  4. 브라우저 표시: 클라이언트는 서버로부터 받은 HTML을 즉시 렌더링하고 화면에 표시합니다.
  5. JavaScript 실행: 페이지가 로드된 후, 클라이언트는 JavaScript를 실행하여 페이지에 동적인 요소를 추가하고, 인터랙티브한 기능을 활성화합니다.

[3]  SSR의 장점

  1. 빠른 초기 로딩:
    • 서버에서 미리 렌더링된 HTML을 클라이언트에 전달하기 때문에, 초기 페이지 로딩 속도가 매우 빠릅니다. 사용자가 페이지를 요청할 때 빠르게 내용을 볼 수 있습니다.
  2. SEO(검색 엔진 최적화):
    • 서버에서 완성된 HTML을 제공하므로 검색 엔진 크롤러가 페이지의 콘텐츠를 쉽게 읽을 수 있습니다. 이는 SEO에 유리한 점으로, 검색 엔진에서 페이지를 더 잘 인식하고 인덱싱할 수 있습니다.
  3. 더 나은 사용자 경험:
    • 초기 페이지가 빠르게 렌더링되기 때문에, 사용자는 페이지를 더 빨리 볼 수 있으며, **사용자 경험(UX)**이 향상됩니다.
  4. 프로그레시브 웹 앱(PWA):
    • SSR은 클라이언트가 JavaScript를 사용할 수 없더라도 서버에서 완전한 페이지를 렌더링하여 사용자에게 표시할 수 있기 때문에, **PWA(프로그레시브 웹 앱)**에도 유용합니다.

[4]  SSR의 단점

  1. 서버 부하:
    • 모든 페이지 렌더링을 서버에서 처리해야 하므로, 서버에 부하가 증가할 수 있습니다. 특히 트래픽이 많은 웹 애플리케이션에서는 서버의 성능 저하가 발생할 수 있습니다.
  2. 느린 동적 인터페이스:
    • 초기 렌더링 후 동적인 기능을 추가하기 위해 JavaScript가 로드되고 실행되어야 하므로, 초기 화면은 빠르게 렌더링되지만 상호작용성은 JavaScript가 실행된 후에 활성화됩니다.
  3. 상태 관리:
    • 서버 측에서 렌더링된 페이지는 클라이언트의 상태를 유지하는 데 어려움이 있을 수 있습니다. 서버와 클라이언트 간의 상태 동기화가 필요할 수 있습니다.

[5]  SSR 사용 사례

  1. 블로그 및 뉴스 사이트:
    • 검색 엔진 최적화(SEO)가 중요한 블로그나 뉴스 사이트에서는 SSR을 사용하여 빠르게 검색 결과에 노출되도록 할 수 있습니다.
  2. 쇼핑몰 사이트:
    • 초기 제품 정보나 카테고리 정보가 서버에서 렌더링된 HTML로 빠르게 로드되고, JavaScript로 동적 요소가 추가되는 쇼핑몰 사이트에서도 유용합니다.
  3. 대규모 웹 애플리케이션:
    • 초기 페이지 로딩 속도를 빠르게 하고, 사용자의 반응을 더 잘 처리하기 위해 SSR을 사용하는 대규모 웹 애플리케이션도 많습니다.

[6]  SSR vs CSR (Client-Side Rendering) 차이점

항목SSR (Server-Side Rendering)CSR (Client-Side Rendering)

페이지 렌더링 서버에서 미리 렌더링 후 HTML 전달 클라이언트에서 JavaScript가 실행되어 렌더링
초기 로딩 속도 빠른 초기 로딩 느릴 수 있음 (JavaScript 로딩 후 렌더링 시작)
SEO 서버에서 완성된 HTML을 제공하므로 SEO에 유리 클라이언트에서 JavaScript로 렌더링되므로 SEO에 불리
서버 부하 서버 부하가 크고, 많은 트래픽을 처리하기 어려울 수 있음 서버 부하가 적고, 클라이언트에서 처리되므로 서버 부하가 적음
동적 기능 서버 측에서 HTML이 이미 렌더링되어 동적 기능이 지연될 수 있음 JavaScript가 실행된 후 동적 기능을 즉시 활성화

 

SEO(Search Engine Optimization)

  • 검색 엔진에서 상위에 노출될 수 있도록 최적화하는 과정을 말한다.

 

CSR(Client Side Rendering)

📌 웹 애플리케이션에서 클라이언트(브라우저)가 웹 페이지를 렌더링하는 방식입니다. 서버는 최소한의 HTML을 클라이언트에 전달하고, 이후 JavaScript가 클라이언트 측에서 실행되어 콘텐츠를 동적으로 렌더링하는 방식입니다.

  1. HTML을 요청한다. 비어있는 HTML을 응답받는다. JS가 존재하는 주소 링크를 응답한다.
  2. 자바스크립트(클라이언트 로직, 렌더링 포함)를 요청한다.
  3. HTTP API 요청을 하고 화면에 필요한 데이터를 JSON 형태(JSON이 아니어도됨)로 응답받는다.
  4. 응답받은 JSON 데이터로 HTML을 동적으로 그린다.

 

[1]  CSR의 작동 원리

  1. 클라이언트 요청:
    • 사용자가 웹 브라우저에서 특정 URL을 요청하면, 서버는 최소한의 HTML 파일을 클라이언트에 전달합니다. 이 HTML은 보통 페이지의 뼈대(구조)만 포함하고 있으며, 실제 콘텐츠는 포함되지 않습니다.
  2. JavaScript 로드:
    • 클라이언트가 받은 HTML은 주로 JavaScript 파일을 불러오는 역할을 합니다. JavaScript는 페이지를 동적으로 렌더링하는 데 필요한 데이터와 로직을 처리합니다.
  3. API 호출:
    • JavaScript는 서버와 API 요청을 통해 데이터를 받아옵니다. 이 데이터는 JSON 형식으로 전달되며, JavaScript는 이 데이터를 바탕으로 페이지를 동적으로 생성합니다.
  4. 동적 렌더링:
    • 받은 데이터를 바탕으로 JavaScript가 HTML을 동적으로 생성하여 화면에 표시합니다. 클라이언트에서 페이지 렌더링이 이루어지므로, 서버는 추가적인 렌더링 작업을 수행하지 않습니다.
  5. 인터랙티브한 페이지:
    • JavaScript는 페이지에서 사용자의 상호작용을 처리하며, 페이지 내에서 동적 콘텐츠 갱신이나 애니메이션 등을 실시간으로 구현합니다.

[2]  CSR의 장점

  1. 서버 부하 감소:
    • 클라이언트 측에서 렌더링을 처리하므로 서버 부하가 감소합니다. 서버는 페이지의 최소한의 HTML만 보내면 되며, 클라이언트에서 나머지 작업을 처리합니다.
  2. 빠른 사용자 경험:
    • 초기 페이지 로딩 후, 페이지 내의 다른 콘텐츠를 동적으로 로드할 수 있습니다. 이는 사용자가 페이지 간 이동을 할 때 빠른 응답 시간을 제공합니다.
  3. 인터랙티브한 경험:
    • CSR은 JavaScript를 사용하여 동적이고 인터랙티브한 사용자 경험을 제공합니다. 버튼 클릭, 폼 제출 등의 인터랙션에 즉각적으로 반응할 수 있습니다.
  4. 클라이언트 측 상태 관리:
    • CSR에서는 클라이언트 측에서 애플리케이션의 상태를 관리할 수 있어, 페이지를 새로고침하지 않고도 실시간으로 UI 업데이트가 가능합니다.
  5. 애플리케이션 로딩 후 빠른 탐색:
    • 한 번 페이지가 로드되면, 후속 페이지들은 빠르게 로드되고 전환됩니다. 이는 **SPA(Single Page Application)**에서 더욱 두드러지며, 페이지를 새로고침하지 않고도 새로운 콘텐츠를 동적으로 로드합니다.

[3]  CSR의 단점

  1. 초기 로딩 속도:
    • CSR은 클라이언트에서 페이지를 렌더링하므로, 초기 페이지 로딩 시에 JavaScript 파일과 데이터를 모두 로드해야 합니다. 이로 인해 초기 로딩 속도가 상대적으로 느릴 수 있습니다.
  2. SEO (검색 엔진 최적화):
    • CSR에서는 JavaScript로 동적으로 콘텐츠를 렌더링하므로, 검색 엔진 크롤러가 자바스크립트로 렌더링된 콘텐츠를 제대로 인식하지 못할 수 있습니다. 이는 SEO에 불리할 수 있습니다. 최근에는 **서버 사이드 렌더링(SSR)**과 결합하거나 프리렌더링을 통해 이 문제를 해결하기도 합니다.
  3. 자바스크립트 의존성:
    • CSR 방식은 JavaScript가 제대로 실행되지 않으면 페이지가 제대로 표시되지 않거나, 애플리케이션이 기능을 제대로 수행하지 않을 수 있습니다. 사용자가 JavaScript를 비활성화한 경우 페이지가 정상적으로 동작하지 않을 수 있습니다.
  4. 클라이언트 성능 문제:
    • 클라이언트(브라우저)가 많은 작업을 처리하므로, 저사양 기기에서는 성능 저하가 발생할 수 있습니다. 특히, 복잡한 애플리케이션에서는 클라이언트가 느려질 수 있습니다.

[4]  CSR과 SSR의 차이점

항목CSR (Client-Side Rendering)SSR (Server-Side Rendering)

렌더링 위치 클라이언트(브라우저)에서 렌더링 서버에서 렌더링 후 클라이언트로 전달
초기 로딩 시간 상대적으로 느릴 수 있음 (JavaScript 로딩이 필요) 빠름 (서버에서 HTML을 미리 렌더링)
SEO SEO에 불리 (검색 엔진 크롤러가 동적 콘텐츠를 제대로 크롤링 못할 수 있음) SEO에 유리 (완성된 HTML을 서버에서 제공)
서버 부하 서버 부하가 적음 (서버는 기본 HTML만 전달) 서버 부하가 클 수 있음 (매 요청마다 페이지를 렌더링)
사용자 경험 더 동적이고 인터랙티브함, 페이지 간 전환 빠름 초기 페이지 로딩이 빠르지만, 이후 전환에 있어 느릴 수 있음
상태 관리 클라이언트에서 상태를 관리 (SPA) 서버에서 상태를 관리 (매 요청마다 새로 렌더링)

[5]  CSR을 사용하는 주요 기술 및 라이브러리

  • React: 동적이고 인터랙티브한 UI를 구성하는 데 사용되는 라이브러리입니다. React는 **SPA (Single Page Application)**을 만들 때 주로 사용됩니다.
  • Vue.js: React와 유사하게 클라이언트 측에서 렌더링되는 웹 애플리케이션을 만들 때 사용하는 JavaScript 프레임워크입니다.
  • Angular: 구글에서 개발한 프레임워크로, CSR을 기반으로 한 대규모 웹 애플리케이션을 구축하는 데 사용됩니다.
  • Next.js: React 기반의 SSR 및 CSR을 지원하는 프레임워크입니다. CSR이 기본이며, SSR도 선택적으로 사용할 수 있습니다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] MVC 패턴  (0) 2024.12.13
[Net] API 설계  (0) 2024.12.12
[Net] Servlet  (1) 2024.12.04
[Net] Web Application  (1) 2024.12.03
[Net] Restful API  (1) 2024.12.02

Servlet

📌 Servlet자바(Java) 언어로 작성된 서버 측 프로그램으로, 주로 웹 애플리케이션에서 클라이언트의 요청을 처리하고 동적으로 응답을 생성하는 데 사용됩니다.

  • JAVA에서 Sevlet은 HttpServlet 클래스를 상속받아 구현되며, Java EE (Enterprise Edition)**의 중요한 구성 요소로, 웹 서버나 웹 애플리케이션 서버에서 실행되며, HTTP 요청을 처리하는 동적 웹 애플리케이션을 만들 수 있게 해줍니다.
  • Servlet은 HTTP 프로토콜 기반 요청(Request) 및 응답(Response)을 처리하는데 사용된다. 

 

[1] Servlet의 주요 기능

  1. HTTP 요청 처리
    • 클라이언트의 요청(GET, POST 등)을 받아들이고, 이를 처리하여 적절한 응답을 생성합니다.
    • 웹 애플리케이션에서 사용자 요청에 따라 동적인 콘텐츠를 반환할 때 사용됩니다.
  2. 동적 콘텐츠 생성
    • 사용자의 요청에 따라 데이터를 생성하거나 변경하고, 이를 동적으로 웹 페이지로 전달합니다.
    • 예를 들어, 사용자 인증, 데이터베이스 질의 결과, 파일 처리 등을 동적으로 수행합니다.
  3. 세션 관리
    • 웹 애플리케이션에서 클라이언트의 상태를 관리하는 데 도움을 줍니다.
    • 클라이언트가 여러 페이지를 요청할 때, 같은 사용자로 인식하도록 세션을 관리합니다.
  4. 비즈니스 로직 처리
    • 데이터베이스와의 상호작용이나 복잡한 계산을 수행하는 비즈니스 로직을 구현할 수 있습니다.
  5. 응답 처리
    • 클라이언트에게 전달할 HTML, JSON, XML 등의 형식으로 응답을 생성합니다.

[2] Servlet의 작동 방식

  1. 클라이언트의 요청
    클라이언트(보통 웹 브라우저)가 특정 URL을 요청합니다. 이 URL은 서버에 있는 Servlet을 호출합니다.

  2. Servlet 컨테이너 처리
    웹 서버 또는 애플리케이션 서버에서 Servlet 컨테이너가 요청을 받아 Servlet 클래스를 실행합니다.
    이때, Servlet 컨테이너는 요청 정보를 HttpServletRequest 객체에 담아 Servlet으로 전달합니다.

  3. 비즈니스 로직 실행
    Servlet은 요청을 처리하기 위해 필요한 비즈니스 로직을 실행합니다. 이 과정에서 데이터베이스와 연동하거나 데이터를 가공할 수 있습니다.

  4. 응답 생성
    Servlet은 응답을 생성하여 클라이언트에게 반환합니다. 이는 HTML, JSON, XML 등 다양한 형식일 수 있습니다.

  5. 클라이언트에 응답 반환
    생성된 응답은 HttpServletResponse 객체를 통해 클라이언트에게 전달됩니다.

[3] Servlet의 주요 메서드

  1. doGet(HttpServletRequest request, HttpServletResponse response)
    • GET 요청을 처리하는 메서드입니다. 웹 페이지 요청, 링크 클릭 등으로 자주 사용됩니다.
  2. doPost(HttpServletRequest request, HttpServletResponse response)
    • POST 요청을 처리하는 메서드입니다. 일반적으로 사용자로부터 데이터를 제출받을 때 사용됩니다.
  3. init()
    • Servlet이 처음 로딩될 때 호출되는 초기화 메서드입니다. 주로 Servlet 객체의 초기화 작업을 처리합니다.
  4. destroy()
    • Servlet이 종료될 때 호출됩니다. 자원 해제 및 정리 작업을 수행하는 데 사용됩니다.

[4] Servlet의 예시

HTTP Request Message 예시

POST /api/users HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

userId=아이디&pssword=비밀번호

 

HTTP Response Message 예시

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423

<html>
	<body>
		...
	</body>
</html>

 

 

  1. 서버와 TCP/IP 연결
  2. HTTP Request Message 필요한 형태로 변환하여 읽기
    1. HTTP Method 및 URL 분석
    2. HTTP Header 분석
    3. HTTP Message Body 읽기 및 변환
  3. 분석한 결과를 통해 프로세스 실행
  4. 비지니스 로직 실행
  5. HTTP Response Message 생성
    1. HTTP Start Line 생성
    2. Header 생성
    3. HTTP Message Body에 응답 데이터를 요청한 형식에 맞춰 응답
    4. 처리가 불가하다면 예외처리
  6. 응답 전달
  7. 연결 종료
  • Servlet을 지원하는 WAS를 사용한다면?
    1. 비지니스 로직 실행

 

@WebServlet("/hello") // 해당 URL에 매핑되는 Servlet
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 응답 콘텐츠 타입 설정
        response.setContentType("text/html");
        
        // 클라이언트에 응답 전송
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello, Servlet!</h1>");
    }
}
  • 위의 코드에서 HelloServlet은 /hello URL로 들어오는 GET 요청을 처리하며, 간단한 HTML 메시지를 반환하는 Servlet입니다

 


[5] Servlet과 JSP의 차이

구분 Servlet JSP (Java Server Pages)
구성 Java 코드로 작성된 클래스 HTML 코드 내에 Java 코드를 삽입하는 형식
주요 용도 비즈니스 로직 처리, HTTP 요청/응답 관리 사용자 인터페이스(HTML) 작성 및 동적 콘텐츠 생성
장점 강력한 제어 흐름과 비즈니스 로직 구현 가능 HTML 기반으로 작성이 쉬우며, 동적 콘텐츠 생성에 유리
단점 HTML 생성 시 복잡한 Java 코드 필요 비즈니스 로직과 UI가 혼합되어 있어 코드 관리가 어려울 수 있음

 


[6] Servlet의 배달 비유

  • 웹 서버배달원이 단순히 포장을 해서 전달하는 역할이라면,
  • Servlet은 배달원이 주문에 맞게 음식을 준비하고 포장하여 고객에게 전달하는 역할입니다.
    • 정적 콘텐츠를 제공하는 웹 서버와 달리, Servlet은 고객이 주문한 대로 동적으로 음식을 만들고 제공하는 역할을 합니다.
  • 엄연히 WAS와는 다르다. 오히려 WAS에서 클라이언트 요청을 처리하고 응답을 생성하는 역활을 하는 자바 클래스이다. = WAS에서 사용되는 클래스이다

 

Servlet 동작 순서

 

1. WAS의 Servlet Container가 servlet 객체를 생성

2. 클라이언트가 해당 servlet을 사용하는 http 요청을 하면, Servlet Container에서 request,response 객체 생성

3. 이때, 쓰레드가 Servlet 객체 호출하고 request,response 객체를 Servlet 객체에 넘겨줌. 

4. request 객체를 활용해 Servlet의 비즈니스 로직 실행. 

5. 응답 결과를 response 객체에 담은 후, Servlet Container에 전달

6. Servlet Container가 http 응답 메시지 생성 후 클라이언트에게 전달 

서블릿은 로딩 시점에 생성될 수도 있고, 최초 요청 시점에서 생성될 수도 있다고 합니다. 그래서 요청시 서블릿 인스턴스가 메모리에 존재하지 않는다면  서블릿 컨테이너는 해당 서블릿을 로드하고 init() 메서드를 통해 초기화한 후, 적재한다고 합니다.
  • 개발자가 하는 일
    1. Request 객체에 담겨져있는 HTTP 요청 정보를 꺼내서 사용한다.
      • 요청 정보(URL, Method, Message Body)를 통해 필요한 기능(비지니스 로직)을 수행한다.
    2. 생선된 Response 객체에 HTTP 응답 정보를 입력한다.

Servlet Container

📌 Servlet을 지원하는 WAS 내부에는 서블릿 컨테이너가 있다. 서블릿 컨테이너는 서블릿을 초기화, 생성, 관리, 호출, 종료하는 역할을 수행한다.

  • Servlet 관리하고 jsp파일을 실행할 수 있게 해주는 것이 Servlet Container입니다. 

  • Servlet의 생명주기
    • Servlet은 서블릿 컨테이너가 생성 및 관리한다.
    • WAS(서블릿 컨테이너 포함)가 종료될 때 Servlet도 함께 종료된다.
  • Servlet 객체 생성시점
    • 개발자가 직접 인스턴스화 하여 사용하는것이 아닌, 코드만 작성하면 서블릿 컨테이너가 생성한다.
@WebServlet(name="ExampleServlet", urlPatterns = "/example")
public class ExampleServlet extends HttpServlet { // HttpServlet을 상속받아 구현한다.
	
	@Override
	protected void service(
		HttpServletRequest request,  // HTTP 요청 정보를 쉽게 사용할 수 있게 만드는 Servlet
		HttpServletResponse response // HTTP 응답 정보를 쉽게 제공할 수 있게 만드는 Servlet
	) {
		// application logic
	}

}
@WebServlet(name="Example2Servlet", urlPatterns = "/example2")
// 위와 같은 코드

@WebServlet(name="Example3Servlet", urlPatterns = "/example3")
// 위와 같은 코드

@WebServlet(name="Example4Servlet", urlPatterns = "/example4")
// 위와 같은 코드
  • Servlet Container가 하는 일
    1. 서블릿을 초기화, 생성, 관리, 호출, 종료하는 역할을 수행한다.
      • Servlet 객체를 싱글톤으로 관리한다.
    2. 동시 요청에 대한 처리를 위해 Multi Thread를 지원한다.
싱글톤은 객체를 하나만 생성하여 생성된 인스턴스를 공유하여 사용하는것을 의미합니다. 특정 클래스의 인스턴스가 여러개 생성되지 않도록 하여 자원의 낭비를 방지하고, 인스턴스를 공유함으로써 상태를 일관되게 유지하기 위함입니다. 하지만, 공유 변수 사용을 주의해야 합니다.

 

 

 

Thread

📌 프로세스 내에서 실행되는 가벼운 작업 단위입니다. 프로세스는 프로그램이 실행되는 환경을 의미하고, 쓰레드는 프로세스 내에서 독립적으로 실행되는 코드의 흐름입니다. 여러 쓰레드는 하나의 프로세스 내에서 공유된 자원(메모리, 파일 등)을 사용하면서 동시에 실행될 수 있습니다.

  • 애플리케이션 코드를 하나하나 순차적으로 실행하는 것, Java에서 main method를 실행하면 main이라는 이름을 가진 Thread가 실행되며 하나의 Thread는 한번에 하나의 코드 라인만 수행한다.
  • 만약 동시 처리가 필요하다면 Thread를 추가적으로 생성 해야한다.

 

Servlet 객체의 호출

  • 클라이언트에서 Request가 전달되면 Thread가 Servlet 객체를 호출한다.

 

[1]  단일 요청 - Single Thread

  1. 클라이언트 요청 및 TCP/IP 연결
  2. Thread 할당 후 Servlet 호출 ( Servlet도 쓰레드에 적재되어 실행하게 된다. 프로그램이 당연하지만)
  3. 응답 후 Thread 반환

[2]  동시 요청 - Single Thread

  1. 첫번째 요청의 작업을 Single Thread가 수행중이다.
  2. 두번째, 세번째 요청이 들어오고 연결을 완료했다.
  3. Thread를 사용하기 위해 작업이 끝날때 까지 대기한다.
  4. 요청이 모두 사라질 때 까지 (대기 → 작업 수행 → 스레드 반환)작업을 반복한다.

 

  • 만약, 첫번째 요청의 작업이 지연되거나 Error가 발생한다면?
더보기

모든 요청이 Time out 오류가 발생한다.

 

[1]  요청마다 새로운 Thread 생성  - Multi Thread

  • 요청이 들어올 때 마다 Thread를 생성한다.
  • 요청 처리가 완료되면 Thread를 종료한다.
  • 멀티 쓰레드는 수행 속도가 빨라 동시에 처리하는 것 같지만 사실 엄청나게 짧은 시간 안에 수십, 수천 번 실행할 프로세스를 교체하고 있는 것이다.

 

  • 장점
    • 동시 요청을 처리할 수 있다.
    • 하나의 Thread에 지연등의 문제가 발생하여도 나머지 Thread는 정상적으로 동작한다.
  • 단점
    • Thread 생성에 제한이 없고 생성 비용이 높다.
      • 수많은 동시 요청이 발생하면 리소스(Memory, CPU 등)부족으로 서버가 다운된다.
    • Thread를 사용하면 Context Switching 비용이 발생한다.
Context Switching



Task1에서 Task2로 Task2에서 Task1로 교체되는 시점마다 Task1이 Ready 상태로 돌아간다는 정보, 진행정보, Task2는 어디부터 작업을 시작하면 되는지에 대한 정보들을 로딩할 시간이 필요하게 된다. 이 순간의 시점이 바로 Context Switching이다.

 

 

[2]  Thread Pool   - Multi Thread

  • 요청이 들어오면 Thread Pool에서 Thread를 받아 사용한다.
  • 사용 완료된 Thread는 Thread Pool에 반납한다.
더보기

Q. Thread Pool에 존재하는 Thread가 모두 사용 중이라면?

A. Thread Pool에 Thread가 생길 때까지 대기하거나 거절할 수 있습니다.

 

정리

  1. WAS는 Multi Thread를 지원한다.
    • 개발자가 Multi Thread 관련 코드는 고려하지 않아도 된다.
    • Multi Thread 환경이므로 싱글톤 객체(Servlet, Spring Bean)는 주의해서 사용해야한다.
    → 공유변수 사용 조심 또 조심!
  2. Thread Pool
    • Thread는 Thread Pool에 보관 및 관리한다.
    • Thread Pool에 생성 가능한 Thread 최대치를 관리한다. Tomcat은 최대 200개 기본 설정이 되어있다.(변경 가능)
      • 성능테스트를 통해 적정 Thread 수를 찾으면 된다.
    • 장점
      1. 요청 마다 Thread를 생성하는 단점을 보완하였다.
      2. Thread가 미리 생성되어 있어서 Thread를 생성, 종료하는 비용이 절약된다. → 응답이 빠름
      3. 생성 가능한 Thread 최대치가 제한되어 있어서 많은 요청이 들어와도 안전하게 처리할 수 있다.
    • 단점
      1. Thread Pool의 최대 Thread 수를 낮게 설정한다면 응답이 지연된다.
      2. 최대 Thread 수가 너무 높으면 즉, 요청이 많아지면 리소스 부족으로 서버가 다운된다.

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] API 설계  (0) 2024.12.12
[Net] Rendering  (1) 2024.12.05
[Net] Web Application  (1) 2024.12.03
[Net] Restful API  (1) 2024.12.02
[Net] HTTP 요청 데이터  (0) 2024.12.02

Web Server

📌 클라이언트(보통 웹 브라우저)의 요청을 받아 정적 리소스(HTML, CSS, JavaScript) 같은 정적 파일 또는 동적 콘텐츠를 제공하는 소프트웨어 또는 하드웨어를 말합니다.

= 클라이언트 요청에 따라 정적 파일(HTML, CSS, JS) 또는 동적 콘텐츠를 제공하는 소프트웨어나 하드웨어

  • 웹 서버는 HTTP 또는 HTTPS 프로토콜을 사용하며, 주로 사용자와 웹 애플리케이션[스프링] 사이에서 데이터를 주고받는 역할을 합니다.
  • 정적 리소스란 리소스가 이미 완성된 채로 서버에 존재하여 원본 그대로 응답하는 데이터를 의미한다.
  • = 다른 데이터는 가공을 처리해서 보내는 것에 반에 정적 리소스는 요청 시 서버에서 따로 데이터를 수정하거나 변형하지 않기 때문에, 서버와 클라이언트 간 추가 작업 없이 바로 사용 가능합니다.
  • 이쯤이면 헷갈릴건데 클라이언트 → 프록시 서버 → 웹 서버 → 웹 애플리케이션 → RDS 현대적인 백엔드 시스템의 흔한 구조를 간단히 표현하면 이렇다

 

미리 로드맵을 알고 가는 것이 좋다 판단하여 아래의 요약본을 보고가는 것을 추천한다.

  하는 일 주요 역할
클라이언트 - HTTP 요청 생성 (예: HTML, API 호출)
- 브라우저, 모바일 앱, 또는 다른 서비스가 요청 전송
- 서버의 응답을 사용자에게 표시
- 데이터를 요청하는 주체.
- 사용자 인터페이스 제공.
- 서버로 요청하고 결과를 화면에 출력.
프록시 서버 - 클라이언트 요청을 분석 및 필터링
- 로드 밸런싱: 요청을 여러 웹 서버로 분배
- 자주 요청되는 데이터 캐싱- 보안 강화 (예: SSL 처리)
- 중개 역할: 클라이언트와 웹 서버 사이에서 요청 처리.
- 캐싱: 정적 리소스를 저장하여 빠른 응답.
- 트래픽 관리 및 부하 분산.
웹 서버 - HTTP 요청 처리
- 정적 리소스(HTML, CSS, JS 등) 제공
- 동적 요청을 WAS로 전달
- 정적 리소스 제공.- 요청이 정적인지 동적인지 구분.
- 동적 요청을 WAS로 전달하여 처리.
WAS (웹 애플리케이션 서버) - 클라이언트 요청 처리(예: 비즈니스 로직 실행)
- 데이터베이스와 통신하여 CRUD 작업 수행
- 요청 결과를 JSON, HTML 등으로 생성 및 반환
- 요청 처리: 클라이언트 요청에 따라 데이터를 생성, 수정, 조회, 삭제.
- 비즈니스 로직 구현.
- RDS와 통신하여 필요한 데이터 제공.
RDS (관계형 데이터베이스) - 데이터를 저장, 관리 및 조회
- SQL 쿼리 처리
- 요청 데이터를 반환하거나 저장
- 영구 데이터 저장.- SQL을 통해 데이터를 읽고 쓰는 작업 수행.
- 관계형 데이터베이스로 데이터 무결성 보장.

요약: 각 파트의 주요 역할

  1. 클라이언트: 요청 생성, 서버로 전송, 응답 데이터 표시.
  2. 프록시 서버: 요청 필터링, 캐싱, 로드 밸런싱, 보안 강화.
  3. 웹 서버: 정적 리소스 제공, 동적 요청은 WAS로 라우팅.
  4. WAS: 비즈니스 로직 처리, 데이터베이스와 통신, 동적 응답 생성.
  5. RDS: 데이터를 저장하고, 읽기/쓰기 요청 처리.

 

 

 

[1] 웹 서버의 주요 기능

  1. HTTP 요청 처리
    • 클라이언트가 보낸 요청(GET, POST 등)을 수신하고 응답을 반환.
    • 정적 콘텐츠(HTML, 이미지) 또는 동적 콘텐츠(애플리케이션 서버와 연계).
  2. 정적 콘텐츠 제공
    • HTML 파일, CSS, JavaScript, 이미지 파일 등을 클라이언트에게 전달.
  3. 동적 콘텐츠 처리
    • PHP, Python, Java 등 애플리케이션 서버와 통신하여 동적으로 생성된 데이터를 반환.
  4. 보안 관리
    • HTTPS를 통한 데이터 암호화.
    • 인증 및 접근 제한 기능 제공.
  5. 로드 밸런싱
    • 여러 서버에 요청을 분산하여 성능을 최적화하고, 고가용성을 유지.

[2] 웹 서버의 작동 방식

  1. 클라이언트(웹 브라우저)가 URL을 통해 서버에 요청을 보냄.
  2. 웹 서버는 요청을 분석하여 처리할 리소스를 결정.
    • 정적 콘텐츠 요청: HTML, CSS 같은 파일을 그대로 반환.
    • 동적 콘텐츠 요청: 애플리케이션 서버에 요청을 전달하고 결과를 받아 반환.
  3. 처리 결과를 HTTP 응답으로 클라이언트에게 전달.

[3] 웹 서버의 예시와 용도

웹 서버 소프트웨어특징

Apache HTTP Server 가장 널리 사용되는 오픈소스 웹 서버. 다양한 플랫폼 지원.
Nginx 가벼운 구조와 높은 성능으로 정적 파일 제공 및 로드 밸런싱에 강점.
IIS Microsoft가 개발한 윈도우 전용 웹 서버. .NET 애플리케이션과의 통합이 강점.
LiteSpeed Nginx와 비슷한 고성능 웹 서버로, 특히 WordPress와의 호환성이 좋음.

[4] 웹 서버와 애플리케이션 서버의 차이

구분 웹 서버 애플리케이션 서버
주요 역할 정적 콘텐츠 제공 동적 콘텐츠 생성
예시 Apache, Nginx Tomcat, WebLogic, JBoss
작동 방식 클라이언트 요청에 HTML, CSS, 이미지 등 반환 서버 로직을 실행하여 동적으로 데이터를 생성하고 반환
연계 단독 또는 애플리케이션 서버와 함께 사용 웹 서버와 연동하여 동작

[5] 웹 서버의 배달 비유

웹 서버는 배달 창구 직원에 비유할 수 있습니다.

  • 요청 분석: 고객(브라우저)이 요청하면 창구 직원이 요청 내용을 확인.
  • 정적 리소스 제공: 창고에서 물건(HTML, CSS, 이미지)을 찾아 전달.
  • 동적 리소스 요청: 필요시 창고 관리자(애플리케이션 서버)에게 요청을 전달하고 결과를 받아 고객에게 전달.
  • 로드 관리: 한 번에 여러 고객을 효율적으로 처리하도록 줄을 정리.

[6] 웹 서버의 장점과 단점

장점 단점
- 빠르고 효율적인 정적 콘텐츠 제공. - 동적 처리를 단독으로 지원하지 못함.
- HTTP 프로토콜 최적화로 요청 처리 속도 향상. - 복잡한 요청(데이터 처리, 비즈니스 로직 등)은 애플리케이션 서버에 의존.
- 다양한 플랫폼과의 호환성. - 상태 비저장 특성으로 특정 작업 지속성을 유지하기 어려움.

 

 

 

WAS(Web Application Server)

📌 웹 애플리케이션을 실행하고 관리하는 서버입니다. 웹 애플리케이션 서버는 동적 콘텐츠 생성비즈니스 로직 처리를 담당하며, 클라이언트의 요청에 따라 애플리케이션 로직을 실행하고 결과를 반환합니다.

  • 웹 서버와는 달리 WAS는 서버 측의 애플리케이션을 실행하고 관리하는 역할을 하며, 일반적으로 웹 서버와 함께 사용되어 동적 콘텐츠 처리를 지원합니다.

 

[1] WAS의 주요 기능

  1. 애플리케이션 실행
    • 클라이언트의 요청에 따라 동적으로 데이터를 생성하고 비즈니스 로직을 실행합니다.
    • 예를 들어, 데이터베이스와 연결하여 정보를 가져오거나, 파일을 처리하거나, 복잡한 계산을 수행하는 등의 작업을 처리합니다.
  2. 세션 관리
    • 사용자 상태를 유지하기 위해 세션을 관리합니다.
    • 클라이언트가 여러 요청을 보내더라도, 서버는 동일한 사용자로 인식하여 일관된 정보를 제공합니다.
  3. 트랜잭션 관리
    • 데이터베이스와의 트랜잭션 처리를 관리하여 일관성 있는 데이터를 제공합니다.
  4. 보안 관리
    • 애플리케이션의 보안을 관리하고, 인증 및 권한 부여를 처리합니다.
  5. 서비스 배포 및 확장
    • 애플리케이션을 배포하고 관리하는 기능을 제공합니다.
    • 확장성을 고려하여 여러 인스턴스로 분산 처리가 가능합니다.

 


[2] WAS와 웹 서버의 차이

특징 웹 서버 웹 애플리케이션 서버 (WAS)
기본 역할 정적 콘텐츠 제공 (HTML, 이미지, CSS 등) 동적 콘텐츠 생성 및 비즈니스 로직 실행
응답 처리 방식 파일을 그대로 전달 (정적 파일 처리) 애플리케이션 로직을 실행하여 데이터를 동적으로 생성
세션 관리 일반적으로 세션 관리가 없거나 제한적 세션 관리 및 트랜잭션 처리
애플리케이션 서버 기능 없음 비즈니스 로직 실행, 데이터베이스 연동, 트랜잭션 관리
사용 예시 웹 페이지의 HTML, 이미지, CSS 파일 제공 온라인 쇼핑몰, 은행 시스템, 사용자 인증 등
  • Web Server와 WAS(Web Application Server)의 차이점
    1. 실제로는 Web Server도 Application 로직을 포함할 수 있다.
    2. WAS는 Application 코드를 실행하는 것에 더욱 특화되어 있다.
    3. Java에서는 Servlet Container 기능을 제공하면 WAS 이다.

[3] WAS의 예시

WAS 소프트웨어특징

Apache Tomcat Java Servlet과 JSP를 지원하는 오픈소스 WAS. 가장 널리 사용됨.
JBoss (WildFly) Java EE 표준을 지원하며, 엔터프라이즈급 애플리케이션을 처리하는 WAS.
WebLogic Oracle의 Java EE 기반 WAS, 고급 트랜잭션 관리와 확장성 제공.
WebSphere IBM의 WAS로, 대규모 기업 환경에서 고급 기능과 안정성 제공.

 


[4] WAS의 배달 비유

  • 웹 서버배달원이 단순히 포장을 해서 전달하는 역할이라면,
  • **웹 애플리케이션 서버(WAS)**는 배달원이 주문에 맞춰 요리를 준비하고, 포장한 뒤 정확하게 전달하는 역할입니다.
    • 즉, 웹 서버는 이미 준비된 음식을 그대로 전달하지만, WAS는 주문에 맞는 음식을 준비하고 그 결과를 고객에게 전달하는 역할을 합니다.

 

 

Web System 구성

 

[1]  WAS만 사용하는 경우

  1. WAS가 너무 많은 역할을 담당한다
    • 서버 과부하 발생 가능성이 높아진다.
  2. 실행에 가장 중요한 Application 로직이 정적 리소스로 인해 수행되지 않을 수 있다.
  3. WAS에 장애가 생기면 아무런 화면도 보여주지 못한다.
    • 오류 페이지를 클라이언트에게 응답할 수 없다.

 

[2]  실제 웹 시스템 구성

  1. 정적 리소스는 Web Server에서 처리한다.
  2. Web Server는 Application 로직이 필요한 요청만을 WAS에 전달한다.

 

[3]  실제 웹 시스템 구성의 장점

  1. 효율적으로 리소스를 관리할 수 있다.
    • 정적 자원이 많이 사용된다면 Web Server를 ScaleOut 한다.
    • Application 관련 자원이 많이 사용된다면 WAS를 ScaleOut 한다.
  2. 오류 화면을 제공할 수 있다.
    • Web Server는 오류가 발생할 확률이 아주 낮다.
    • WAS는 오류가 발생할 확률이 아주 높고, 장애가 자주 발생한다.
    • WAS는 DB와 상호작용 하기 때문에 DB에 문제가 생겨도 문제가 발생한다.

 

'CS ( Computer Science ) > 네트워크 (Networking)' 카테고리의 다른 글

[Net] Rendering  (1) 2024.12.05
[Net] Servlet  (1) 2024.12.04
[Net] Restful API  (1) 2024.12.02
[Net] HTTP 요청 데이터  (0) 2024.12.02
[Net] HTTP Header  (0) 2024.12.01

+ Recent posts