사용자 환경 설정, 사용자 맞춤화, 사용자 추적, 광고 타깃팅과 같이 사용자에게 노출되어도 괜찮은 데이터를 저장하거나, 클라이언트 측에서 정보를 지속적으로 활용해야 할 때 사용됩니다.
대부분의 웹 애플리케이션은 세션과 쿠키를 조합하여 사용하며, 각각의 장점을 최대한 활용하려고 노력합니다. 예를 들어, 세션을 사용하여 인증 정보를 안전하게 보관하고, 쿠키를 사용하여 사용자의 선호 설정을 저장할 수 있습니다.
CRUD 기능을 전부 POST METHOD로만 처리하는 API
URI에 자원과 id외 정보가 들어가는 경우PUT /users/update-nickname [X] PUT /users/:id/nickname [O]
자원 식별 불일치 (Resource Mismatch): RESTful 아키텍처에서는 각 리소스에 대한 고유한 식별자(URI)를 가져야 합니다. RESTful하지 못한 경우, 리소스가 잘못 식별되거나 URI 구조가 일관성 없이 정의됩니다.
HTTP 메서드 오용 (HTTP Method Misuse): HTTP 메서드(GET, POST, PUT, DELETE 등)를 잘못 사용하는 경우 RESTful하지 못합니다. 예를 들어, 모든 작업을 POST 메서드로만 처리하는 것은 RESTful하지 않습니다. 각 메서드는 특정한 의미와 목적을 가져야 합니다.
상태 저장 (Stateful): RESTful 아키텍처는 상태를 클라이언트 측에서 관리하지 않는 무상태(Stateless) 아키텍처를 권장합니다. 상태 저장은 클라이언트와 서버 간 통신의 복잡성을 증가시키고 확장성을 감소시키므로 RESTful하지 못한 것으로 간주됩니다.
서버 측 동작 부족 (Lack of Server-Side Behavior): RESTful 서비스는 서버 측에서 리소스와 상호작용하는 동작을 정의해야 합니다. 일부 웹 서비스는 클라이언트 측에서 모든 동작을 수행하고 서버 측에서는 단순히 데이터 저장소 역할만 하는 경우 RESTful하지 않습니다.
무의미한 URI: URI 디자인이 비의미적이고 각 리소스의 경로가 일관성이 없을 때 RESTful하지 못합니다. 명확하고 의미 있는 URI는 API의 가독성을 높이고 이해하기 쉽게 만듭니다.
상태 전이 (State Transition): RESTful 아키텍처에서 상태 전이는 상태가 변경되는 과정을 의미합니다. 상태 전이가 모호하거나 제대로 정의되지 않은 경우 RESTful하지 못합니다.
미디어 타입 이슈: RESTful 서비스에서는 클라이언트와 서버 간의 데이터 교환을 위한 적절한 미디어 타입을 사용해야 합니다. 미디어 타입이 잘못 정의되거나 일관성이 없는 경우 RESTful하지 않을 수 있습니다.
보안 문제: RESTful 서비스는 보안을 고려해야 합니다. 적절한 인증 및 권한 부여 메커니즘이 없거나 보안 문제가 무시되는 경우 RESTful하지 않을 수 있습니다.
- 안티패턴으로 설계될 가능성이 높다.
전통적인 통신방법에도 HTTP 메서드와 Json 형식을 이용한 통신은 흔한 방식이었습니다. REST API에 대한 이해도가 떨어질 경우 단순히 통신방법이 유사하다고 "REST를 쓴다."라고 생각할 수 있습니다. 그렇기에 초창기부터 지금까지 REST API 중에는 안티패턴을 사용하는 경우가 항상 존재했습니다.
REST API의 안티패턴이란 REST API의 특징을 이해하지 못하고 REST 사상에 어긋나는 패턴을 적용한 API들을 말합니다. 안티패턴의 사용은 설계자의 무능함이라 볼 수 없습니다. REST 자체가 흔히 사용하는 기술을 응용하여 사용했기 때문에 설계자의 지식 기반으로 설계될 수 있습니다. 즉 틀린 지식이 아닌, 관점이 다른 지식을 사용하여 설계를 진행했기에 안티패턴이 될 가능성이 높습니다.- 표준 규약이 없다.
REST는 표준이 없습니다. 그렇기에 관리가 쉽지 않습니다. 표준이 없다 보니 성공적인 REST API 사례를 근거로 암묵적인 규칙이 생기기도 하는데 Google, Netflix, Amazone 등의 기업들이 REST의 표준역할을 하고 있습니다. 그렇다 보니 실제 REST API를 설계하는 담당자도 현 정책의 판단의 기준을 자의적으로 할 수밖에 없으며 더 안티패턴의 형태로 발전하는 경향이 있습니다.- RDBMS의 표현에 적합하지 않다.
RDBMS는 다양한 키들이 존재합니다. REST API는 리소스를 표현할 때 나열하기 용의한 형태 (Json, XML...)를 사용하기 때문에 RDBMS에 표현이 적합하지 않을 수 있습니다.
Connection Timeout은 서버와의 연결을 설정하는 데 걸리는 시간을 제한하고, Read Timeout은 서버로부터 데이터를 수신하는 데 걸리는 시간을 제한합니다. 이 두 가지 타임아웃은 네트워크 통신 중 문제를 감지하고 대응하는 데 도움을 줍니다.
Connection Timeout은 클라이언트가 서버에 연결을 시도하고 있을 때, 서버로의 연결이 성립되지 않는 경우 발생합니다. 이 타임아웃은 클라이언트가 서버로의 연결을 설정하는 데 소요되는 시간을 제어합니다. 일반적으로 서버가 다운되거나 네트워크 문제로 연결이 불가능한 경우에 발생합니다.
Read Timeout은 클라이언트가 서버에 연결을 설정하고 요청을 보낸 후, 서버가 응답을 보내지 않는 경우 발생합니다. 클라이언트가 서버로의 연결을 성공적으로 설정하고 데이터를 요청한 후에 발생합니다. 이 타임아웃은 클라이언트가 서버로부터 데이터를 읽는 데 소요되는 시간을 제어합니다. 일반적으로 서버가 응답을 처리하는 데 시간이 오래 걸리거나, 네트워크 지연으로 인해 응답이 느리게 전송되는 경우에 발생합니다.
(자세히)
방화벽은 실질적으로 IP/Port 기반으로 차단하는 솔루션으로, 외부에서 내부로 반드시 들어와야 하는 서비스를 모두 허용으로 설정합니다. 예를 들어 웹/메일 서비스와 같은 경우에는 방화벽은 외부에서 누가 들어올 지 정의할 수 없으므로, 관련 서비스 포트를 모두 허용으로 설정해야 합니다.
그렇게 되면, 일반 유저뿐만 아니라 악의적인 의도를 가진 해킹/악성코드/스팸메일 등도 여과없이 들어올 수 밖에 없으므로, 이러한 방화벽의 한계점을 보완하기 위해(대체는 아님) 나온 솔루션이 침입 탐지(IDS)/방지(IPS) 시스템입니다.

_- 방화벽 : 미리 정의된 보안 규칙에 기반한, 들어오고 나가는 네트워크 트래픽을 모니터링하고 제어하는 네트워크 보안 시스템
근래에 도입되는 솔루션은 대부분은 IPS이다.
서버는 CA(인증기관)에 사이트 정보와 공개 키를 전달하여 인증서를 받음 → 클라이언트는 브라우저에 CA 공개 키가 내장되어 있다고 가정 → ClientHello(암호화 알고리즘 나열 및 전달) → ServerHello(암호화 알고리즘 선택) → Server Certificate(인증서 전달) → Client Key Exchange(데이터를 암호화 할 대칭 키 전달) → Client / ServerHello done (정보 전달 완료) → Finished(SSL Handshake 종료)
어떤 사람은 SSL Handshake 과정을 손으로 그려 보세요.라는 질문을 받았다고 한다.
SOP (Same-Origin Policy)는 웹 보안 모델 중 하나로, 웹 페이지의 스크립트가 동일한 출처 (Origin)에서 로드된 문서와만 상호 작용할 수 있도록 제한하는 보안 기술입니다. 출처란 프로토콜 (http 또는 https), 호스트 (도메인), 포트 번호로 구성됩니다. 이 정책은 웹 애플리케이션의 보안을 강화하고 다른 출처로부터의 악의적인 스크립트로부터 사용자의 데이터와 브라우징 환경을 보호합니다.
SOP는 다음과 같은 제약 사항을 적용합니다:
- 동일 출처 정책: 스크립트가 로드된 출처와 데이터에 액세스하려는 대상 출처가 동일해야 합니다. 다른 출처에 대한 직접적인 접근은 허용되지 않습니다.
- 쿠키 및 헤더: 동일한 출처 정책은 쿠키 및 HTTP 헤더에도 적용됩니다. 따라서 다른 출처의 페이지에서는 해당 출처에 대한 쿠키나 헤더에 액세스할 수 없습니다.
CORS (Cross-Origin Resource Sharing)는 SOP의 엄격한 규칙을 완화하기 위해 도입된 웹 표준입니다. CORS는 다른 출처로부터의 요청에 대한 접근을 서버가 허용하도록 허용하며, 웹 애플리케이션 간의 자원 공유를 가능하게 합니다.
- 요청 헤더: 브라우저는 다른 출처로의 HTTP 요청을 보낼 때 요청 헤더에 Origin 헤더를 포함합니다. 이 헤더는 요청이 어떤 출처에서 시작되었는지를 나타냅니다.
- 응답 헤더: 서버는 요청된 자원에 대한 응답을 반환할 때 Access-Control-Allow-Origin 헤더를 사용하여 허용된 출처를 지정합니다. 이 헤더를 통해 브라우저는 해당 출처에서만 접근이 허용되는지 확인합니다.
- 전파: 브라우저는 서버로부터 받은 응답 헤더를 검사하고, 허용된 출처에서만 접근이 가능한 경우 자원을 사용합니다. 그렇지 않은 경우 브라우저에서는 보안 오류가 발생합니다.
이러한 CORS의 요청방식에는 크게 두 가지 방식이 있습니다. 바로 Simple Request와 Preflight Request입니다.
Simple Request

다음과 같은 조건을 만족하면, 브라우저는 해당 CORS 요청을 Simple Request로 처리합니다.
HTTP Method가 GET, POST, HEAD 중 하나인 경우
Content-Type 헤더가 다음 중 하나인 경우
application/x-www-form-urlencoded
multipart/form-data
text/plain
CORS-safelisted request-header를 포함하는 경우(Fetch spec)
XMLHttpRequest.upload 에 이벤트 핸들러, 리스너가 등록되지 않은 경우
ReadableStream 객체가 포함되지 않은 경우
Simple Request의 경우 다음과 같은 방식으로 동작합니다.
사용자가 요청 헤더에 자신의 Origin을 실어서 서버로 요청을 보낸다.
서버는 요청 헤더의 Origin을 확인한다.
CORS 요청이 유효하다면 서버는 응답 헤더에 Accecss-Control-Allow-Origin 헤더를 추가해 사용자에게 다시 전송한다.
브라우저는 서버에 CORS 요청을 보내면 응답 헤더에 Access-Control-Allow-Origin 헤더를 보고 응답의 허용여부를 결정합니다. Access-Control-Allow-Origin은 응답 헤더 리스트중 하나입니다. Access-Control-Allow-Origin을 * 로 설정하면 브라우저는 credentials 옵션이 없는 요청에 한해 모든 Origin이 해당 리소스에 접근 가능하도록 허용해줍니다.
Preflight Request

Preflight Request는 Simple Request의 조건을 만족하지 못할시 브라우저가 자동으로 생성합니다. Simple Request와 달리 OPTIONS 메서드를 통해 다른 Origin의 리소스로 HTTP 요청을 미리 보내(preflight) 실제 요청이 전송하기에 안전한지 확인합니다. 브라우저는 안전하다고 판단되면 이를 통해 실제 요청을 보내게 됩니다. Cross-Origin 요청의 경우 유저 데이터에 영향을 줄 수 있기 때문에 이와 같이 미리 전송(preflight)합니다.
프리플라이트 요청을 통해 서버는 요청이 실행되기 전에 검사하고 허용 여부를 표시할 기회를 얻을 수 있기 때문입니다. 그리고 서버가 다른 출처에서 허용하지 않는 특정 요청을 차단함으로써 서버를 보호하는데 도움을 줍니다.

_access -control-allow-origin 헤더는 서버가 허용할 요청을 표시하는 데 사용할 수 있는 주요 CORS 헤더 중 하나입니다. 이 헤더의 값은 브라우저에 특정 출처에 대한 액세스를 허용하도록 지시하는 단일 출처일 수도 있고, 브라우저에 모든 출처를 허용하도록 지시하는 것일 수도 있습니다.
서버가 이 헤더로 응답하지 않거나 헤더 값이 요청 원본과 일치하지 않는 도메인인 경우 그러면 브라우저는 응답이 스크립트로 다시 전달되는 것을 방지합니다. 이로 인해 콘솔 오류가 발생할 수 있습니다. _
프리플라이트 요청이란 실제 요청을 보내기 전에 브라우저는 이러한 유형의 요청을 허용하는지 서버에 확인하는 요청이다. 실행 전 요청이라함은 다음 헤더를 포함하는 OPTIONS 요청이다.
- origin : 서버에 요청이 오는 출처를 알려준다.
- access-control-request-method : 요청이 구현하는 HTTP 메서드를 서버에 알려준다.
- access-control-request-headers : 요청이 포함된 헤더를 서버에 알려준다.
이에 대한 응답으로 서버는 다음 헤더로 응답하여 이 출처에서 이러한 종류의 요청을 수락할지 여부를 결정할 수 있다.
- access-control-allow-origin – 서버가 허용할 원본
- access-control-allow-methods – 서버에서 허용할 쉼표로 구분된 메서드 목록
- access-control-allow-headers – 서버에서 허용하는 쉼표로 구분된 헤더 목록
- access-control-max-age – 실행 전 요청에 대한 응답을 캐시하는 시간(초)을 브라우저에 알려준다.
127.0.0.1은 루프백(loopback) 혹은 로컬호스트 주소(localhost)라고도 불립니다. 만약 목적지 IP 주소를 127.0.0.1로 설정하게 되면 A의 네트워크 계층은 이 패킷을 외부로 전송하지 않기 때문입니다. 즉 자신이 송신한 패킷을 그대로 수신한 효과를 가집니다. 예약된 주소로 할당할 수 없는 주소이며 자체 IP에서 할당 작동하여 인터넷이 연결되어있지 않아도 작동합니다. 127.0.0.1을 치기 귀찮아서 localhost를 쓰게되었습니다.
L4 로드밸런싱의 경우 패킷 페이로드까지 접근하지 않아 속도가 빠르고 자원 효율이 좋으며 비용이 저렴하지만 세밀한 로드밸런싱이 어렵고 서버와의 4계층 연결이 끊어지지 않는 이상 장애를 판단하기 어렵습니다. L7 로드밸런싱의 경우 비정상 트래픽을 판단할 수 있고 정교한 로드밸런싱이 가능하지만 비용이 크고 속도와 자원 효율성이 감소합니다.
L4 로드밸런싱
L7 로드밸런싱
여기서 주의할 점은 로드밸런서 또한 일종의 장치이기때문에 다중화 등 장애 대비책을 마련해야한다는 것이다.
네트워크 스위치는 클라이언트를 요청한 주소에 맞게 목적지와 중계해주는 역할을 한다. 이는 스위치 레이어 레벨에 관계 없이 서버의 실제 주소를 숨기는 역할을 한다. 특히 L4/L7스위치는 로드밸런싱의 기능을 수행한다.
L4 스위치
클라이언트 요청의 프로토콜 헤더(IP, PORT)를 기반으로 Source IP와 Destination IP를 변조해 다중화된 서버와 중계해주는 역할을 하기에 IP, PORT 를 기반으로 한 로드밸런싱을 수행한다.
클라이언트가 TCP 프로토콜로 서버에 접속하려 할 경우 목적지 서버와 연결 성립 과정(3-Way HandShake)을 거쳐 커넥션이 생성되는데 L4스위치에서도 커넥션 데이터를 생성해 관리한다.
이때 연결이 일정시간동안 사용되지 않을 경우 커넥션을 삭제하는 값을 가진다.
L7 스위치
어플리케이션 계층에서 동작하는 L7 스위치는 트래픽 내용(URI, Payload, Cookie, HTTP 헤더 등)을 직접 분석할 수 있어 L4 스위치보다 정교한 로드밸런싱에 사용된다.
L4 스위치에 비해 자원의 소모가 크다.
공통점
차이점