컴퓨터는 다른 외부 장치들과 어떻게 데이터를 주고받을까?

 

입출력장치는 종류가 너무나도 많다. 장치가 다양하면 장치마다 속도, 데이터 전송 형식 등도 다양하다.

-> 다양한 입출력장치와 정보를 주고받는 방식을 규격화하기 어렵다.

 

일반적으로 CPU와 메모리의 데이터 전송률은 높지만 입출력장치의 데이터 전송률은 낮다.

* 전송률 : 데이터를 얼마나 빨리 교황할 수 있는지를 나타내는 지표

 

이러한 문제점들을 어떻게 해결할 수 있을까?

 

 

 

장치 컨트롤러

입출력 장치는  장치 컨트롤러를 통해 컴퓨터와 연결된다.

 

장치 컨트롤러의 역할에는 다음과 같은 것들이 있다.

  • CPU와 입출력장치 간의 통신중개 (일종의 번역가 역할을 수행)
  • 오류 검출
  • 데이터 버퍼링 (전송률이 높은 장치와 낮은 장치 사이에 주고받는 데이터를 버퍼라는 임시 저장 공간에 저장하여 전송률을 비슷하게 맞추는 방법)

 

장치 컨트롤러의 구조

장치 컨트롤러의 구조

 

 

 

장치 드라이버

장치 컨트롤러의 동작을 감지하고 제어하는 프로그램.

 

장치 컨트롤러가 입출력장치를 연결하기 위한 하드웨어적인 통로라면, 장치 드라이버는 입출력장치를 연결하기 위한 소프트웨어적인 통로

이다.

장치 드라이버

 

컴퓨터가 연결된 장치의 드라이버를 인식하고 실행할 수 있다면 컴퓨터 내부와 정보를 주고받을 수 있고, 반대로 컴퓨터가 장치 드라이버를 인식하거나 실행할 수 없다면 그 장치는 컴퓨터 내부와 정보를 주고받을 수 없다.

 

이 말을 다시 하면

 

운영체제가 연결된 장치의 드라이버를 인식하고 실행할 수 있다면 컴퓨터 내부와 정보를 주고받을 수 있고, 반대로 운영체제가 장치 드라이버를 인식하거나 실행할 수 없다면 그 장치는 컴퓨터 내부와 정보를 주고받을 수 없다는 것이다.

'컴퓨터구조와 운영체제' 카테고리의 다른 글

운영체제의 큰 그림  (3) 2024.08.28
운영체제를 알아야 하는 이유  (1) 2024.08.14
RAID 정의와 종류  (0) 2024.08.08
보조기억장치  (1) 2024.07.20
캐시 메모리  (0) 2024.07.12

유튜브에서 FastAPI 관련한 영상을 봤는데 너무 간편해보여 찍먹을 해보려고 한다.

 

FastAPI는 API를 만들기 위한 파이썬 웹 프레임워크이다. FastAPI는 이름에 걸맞게 빠른 속도를 자랑한다. 높은 성능과 쉬운 사용성을 목표로 설계되었으며, 대규모 애플리케이션 부터 간단한 프로젝트까지 다양한 요구 사항을 만족시킬 수 있다.

더보기

API(Application Programming Interface)는 서비스의 요청과 응답에 대한 규칙을 의미하지만 보통 API라고 하면 이러한 요청과 응답을 처리하는 서비스(기능)을 의미한다.

 

주요 특징으로는

  1. 고성능 : 비동기 프로그래밍을 지원한다. 내부적으로 Starlette 라는 비동기 프레임워크를 사용한다.
  2. 쉬운 사용성 : Python의 타입 힌트를 활용하여 자동으로 요청 데이터를 검증하고 문서화한다. 이를 통해 개발자는 코드 작성과 동시에 API 문서를 쉽게 생성할 수 있다.
  3. 자동 문서화 : 자동으로 API 문서를 생성한다. Swagger UI와 ReDoc을 통해 직관적이고 사용하기 쉬운 API 문서를 제공한다.
  4. 보안 및 검증 : 데이터 검증과 보안을 간편하게 처리할 수 있는 도구를 제공한다. Pydantic을 사용하여 입력 데이터의 유효성을 검사하고, OAuth2, JWT 등 다양한 인증 방식을 지원한다.
  5. 유연성 : 플러그인과 확장이 용이하며, 다양한 데이터베이스와의 통합 및 외부 라이브러리 사용이 쉽다. 

 

간단한 예시

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: str = None
    price: float
    tax: float = None

@app.get("/")
async def read_root():
    return {"message": "Welcome to FastAPI"}

@app.post("/items/")
async def create_item(item: Item):
    return {"item": item}

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

 

위의 코드는 FastAPI를 사용하여 기본적인 CRUD 기능을 제공하는 API를 구성하는 예시이다. 'Item' 모델을 정의하고, GET 및 POST 요청을 처리하는 엔드포인트를 설정하였다.

 

 

FastAPI 프로젝트 구조 

my_fastapi_project/
    ├── app/
    │   ├── __init__.py
    │   ├── main.py
    │   ├── core/
    │   │   ├── __init__.py
    │   │   ├── config.py
    │   │   └── security.py
    │   ├── models/
    │   │   ├── __init__.py
    │   │   └── user.py
    │   ├── schemas/
    │   │   ├── __init__.py
    │   │   └── user.py
    │   ├── crud/
    │   │   ├── __init__.py
    │   │   └── user.py
    │   ├── db/
    │   │   ├── __init__.py
    │   │   ├── base.py
    │   │   └── session.py
    │   ├── api/
    │   │   ├── __init__.py
    │   │   └── api_v1/
    │   │       ├── __init__.py
    │   │       ├── endpoints/
    │   │       │   ├── __init__.py
    │   │       │   └── users.py
    │   │       └── api.py
    │   ├── tests/
    │   │   ├── __init__.py
    │   │   └── test_user.py
    ├── alembic/
    │   └── (alembic migration files)
    ├── .env
    ├── .gitignore
    ├── requirements.txt
    ├── README.md

 

 

각 디렉토리와 파일의 역할

 

  • app/: 애플리케이션의 주요 코드가 위치하는 디렉토리입니다.
    • main.py: FastAPI 애플리케이션 인스턴스를 생성하고, 라우터를 포함한 초기 설정을 담당합니다.
    • core/: 설정, 보안, 유틸리티 함수 등을 포함합니다.
      • config.py: 애플리케이션 설정을 관리합니다.
      • security.py: 보안 관련 설정과 유틸리티를 포함합니다.
    • models/: SQLAlchemy 모델 정의를 포함합니다.
      • user.py: 사용자 모델을 정의합니다.
    • schemas/: Pydantic 모델 정의를 포함합니다.
      • user.py: 사용자 스키마를 정의합니다.
    • crud/: 데이터베이스 조작(CRUD) 함수가 포함됩니다.
      • user.py: 사용자 관련 CRUD 함수들을 포함합니다.
    • db/: 데이터베이스 설정 및 초기화 스크립트를 포함합니다.
      • base.py: Base 모델과 관련된 설정을 포함합니다.
      • session.py: 데이터베이스 세션을 관리합니다.
    • api/: 라우터 및 엔드포인트를 정의합니다.
      • api_v1/: API 버전 1과 관련된 엔드포인트를 포함합니다.
        • endpoints/: 특정 엔드포인트 모듈을 포함합니다.
          • users.py: 사용자 관련 엔드포인트를 정의합니다.
        • api.py: 버전 1의 API 라우터를 정의하고 등록합니다.
    • tests/: 테스트 코드가 포함됩니다.
      • test_user.py: 사용자 관련 테스트를 포함합니다.
  • alembic/: 데이터베이스 마이그레이션 파일을 포함합니다.
  • .env: 환경 변수를 저장하는 파일입니다.
  • .gitignore: Git에서 무시할 파일과 디렉토리를 정의합니다.
  • requirements.txt: 프로젝트에서 필요한 패키지를 명시합니다.
  • README.md: 프로젝트에 대한 설명을 포함합니다.

 

 웹 서버는 서로 다른 수천 개의 클라이언트들과 동시에 통신한다. 이 서버들은 익명의 클라이언트로부터 받는 모든 요청을 처리하는 것뿐만 아니라 서버와 통신하고 있는 클라이언트를 추적해야 할 수도 있다. 

 

 HTTP는 익명으로 사용하며 상태가 없고 요청과 응답으로 통신하는 프로토콜이다. 웹 서버는 요청을 보낸 사용자를 식별하거나 방문자가 보낸 연속적인 요청을 추적하기 위해 약간의 정보를 이용할 수 있다.

 

개별 인사

온라인 쇼핑이 개인에게 맞춰져 있는 것처럼 느끼게 하려고 사용자에게 특화된 환영 메시지나 페이지 내용을 만든다.

 

사용자 맞춤 추천

온라인 상점은 고객의 흥미가 무엇인지 학습해서 고객이 좋아할 것이라고 예상되는 제품들을 추천할 수 있다. 고객의 생일이나 다른 중요한 날이 다가오면 특별한 제품을 제시하기도 한다.

 

저장된 사용자 정보

온라인 쇼핑 고객은 복잡한 주소와 신용카드 정보를 매번 입력한느 것을 싫어한다. 이런 정보를 데이터베이스에 저장하는 온라인 상점도 있다. 온라인 쇼핑이 당신을 한번 식별하고 나면, 쇼핑을 더 편하게 할 수 있게 저장된 사용자 정보를 사용할 수 있다.

 

세션 추적

HTTP 트랜잭션은 상태가 없다. 각 요청 및 응답은 독립적으로 일어난다. 많은 웹사이트에서 사용자가 사이트와 상호작용할 수 있게 사용자의 상태를 남긴다. 이렇게 상태를 유지하려면, 웹 사이트는 사용자에게서 오는 HTTP 트랜잭션을 식별할 방법이 필요하다.

 

사용자 식별 기술에는 다음과 같은 것이 있다.

 

  • 사용자 식별 관련 정보를 전달하는 HTTP 헤더들
  • 클라이언트IP 주소 추적으로 알아낸 IP 주소로 사용자를 식별
  • 사용자 로그인 인증을 통한 사용자 식별
  • URL에 식별자를 포함하는 기술인 뚱뚱한(fat) URL
  • 식별 정보를 지속해서 유지하는 강력하면서도 효율적인 기술인 쿠키

 

 

HTTP 헤더

 

사용자에 대한 정보를 전달하는 HTTP 헤더

 

위 표는 사용자에 대한 정보를 저장하는 가장 일반적인 일곱 가지 HTTP 요청 헤더가 기술되어 있다. 

 

 

클라이언트 IP 주소

 웹 서버는 HTTP 요청을 보내는 반대쪽 TCP 커넥션의 IP 주소를 알아낼 수 있다. 하지만 클라이언트 IP 주소로 사용자를 식별하는 방식은 다음과 같은 약점을 갖는다.

  • 클라이언트 IP 주소는 사용자가 아닌, 사용하는 컴퓨터를 가리킨다. 만약 여러 사용자가 같은 컴퓨터를 사용한다면 그들을 식별할 수 없다.
  • 많은 인터넷 서비스 제공자(ISP)는 사용자가 로그인하면 동적으로 IP 주소를 할당한다. 로그인한 시단에 따라, 사용자는 매번 다른 주소를 받으므로, 웹 서버는 사용자를 IP 주소로 식별할 수 없다.
  • 보안을 강화하고 부족한 주소들을 관리하려고 많은 사용자가 네트워크 주소 변환(Network Address Translation, NAT) 방화벽을 통해 인터넷을 사용한다. 이 NAT 장비들은 클라이언트의 실제 IP 주소를 방화벽 뒤로 숨기고, 클라이언트의 실제 IP 주소를 내부에서 사용하는 하나의 방화벽 IP 주소로 변환한다.
  • HTTP 프락시와 게이트웨이는 원 서버에 새로운 TCP 연결을 한다. 웹 서버는 클라이언트의 IP 주소 대신 프락시 서버의 IP 주소를 본다. 

 

사용자 로그인

 IP 주소로 사용자를 식별하려는 수동적인 방식보다, 웹 서버는 사용자 이름과 비밀번호로 인증(로그인)할 것을 요구해서 사용자에게 명시적으로 식별 요청을 할 수 있다.

 웹 사이트 로그인이 더 쉽도록 HTTP는 WWW-Autenticate 와 Authorication 헤더를 사용해 웹 사이트에 사용자 이름을 전달하는 자체적인 체계를 가지고 있다. 한번 로그인하면, 브라우저는 사이트로 보내는 모든 요청에 이 로그인 정보를 함께 보내므로 웹 서버는 그 로그인 정보는 항상 확인할 수 있다. 

HTTP 인증 헤더를 이용한 사용자 등록

 

 

뚱뚱한 URL

 어떤 웹 사이트는 사용자의 URL 마다 버전을 기술하여 사용자를 식별하고 추적하였다. 보통, URL은 URL 경로의 처음이나 끝에 어떤 상태 정보를 추가해 확장한다. 사용자가 그 사이트를 돌아다니면, 웹 서버는 URL에 있는 상태 정보를 유지하는 하이퍼링크를 동적으로 생성한다.

 사용자의 상태 정보를 포함하고 있는 URL을 뚱뚱한 URL이라고 한다.

뚱뚱한 URL 예시

 

 

하지만 이 기술에는 여러 문제가 있다.

 

못생긴 URL

브라우저에 보이는 뚱뚱한 URL은 새로운 사용자들에게 혼란을 준다.

 

공유하지 못하는 URL

뚱뚱한 URL은 특정 사용자와 세션에 대한 상태 정보를 포함한다. 만약 그 주소를 누군가에게 메일로 보내면, 당신의 누적된 개인 정보를 본의 아니게 공유하게 된다.

 

캐시를 사용할 수 없음

URL로 만드는 것은 URL이 달라지기 때문에 기존 캐시에 접근할 수 없다는 것을 의미한다.

 

서버 부하 가중

서버는 뚱뚱한 URL에 해당하는 HTML 페이지를 다시 그려야 한다.

 

이탈

사용자가 링크를 타고 다른 사이트로 이동하거나 특정 URL을 요청해서 의도치 않게 뚱뚱한 URL 세션에서 '이탈'하기 쉽다. 사용자는 서비스를 사용하는 동안, 사전에 세션 정보가 추가된 링크만을 사용해야 뚱뚱한 URL이 문제없이 동작할 수 있다.

 

세션 간 지속성의 부재

사용자가 특정 뚱뚱한 URL을 북마킹하지 않는 이상, 로그아웃하면 모든 정보를 잃는다.

 

 

쿠키

 쿠기는 사용자를 식별하고 세션을 유지하는 방식 중에서 현재까지 가장 널리 사용하는 방식이다. 

 

쿠키의 타입

 쿠키는 크게 세션 쿠키(session cookie)와 지속 쿠키(persistent cookie) 두 가지 타입으로 나눌 수 있다. 세션 쿠키는 사용자가 사이트를 탐색할 때, 관련한 설정과 선호 사항들을 저장하는 임시 쿠키다. 세션 쿠키는 사용자가 브라우저를 닫으면 삭제된다. 지속 쿠키는 삭제되지 않고 더 길게 유지될 수 있다. 지속 쿠키는 디스크에 저장되어, 브라우저를 닫거나 컴퓨터를 재시작하더라도 남아있다. 지속 쿠키는 사용자가 주기적으로 방문하는 사이트에 대한 설정 정보나 로그인 이름을 유지하려고 사용한다. 

 

세션 쿠키와 지속 쿠키의 다른 점은 파기되는 시점뿐이다.

 

쿠키는 어떻게 동작하는가

 쿠키는 서버가 사용자에게 "안녕, 내 이름은.."라고 적어서 붙이는 스티커와 같다. 사용자가 웹 사이트에 방문하면, 웹 사이트는 서버가 사용자에게 붙인 모든 스티커를 읽을 수 있다.

  

 웹 서버는 사용자가 다시 돌아왔을 때, 해당 사용자를 식별하기 위한 유일한 값을 쿠키에 할당한다. 쿠키는 임의의 이름=값 형태의 리스트를 가지고, 그 리스트는 Set-Cookie 혹은 Set-Cookie2(확장 헤더) 같은 HTTP 응답 헤더에 기술되어 사용자에게 전달한다.

 

 쿠키는 어떤 정보든 포함할 수 있지만, 서버가 사용자 추적 용도로 생성한 유일한 단순 식별 번호만 포함하기도 한다.

 

 

쿠키 상자 : 클라이언트 측 상태

쿠키의 기본적인 발상은 브라우저가 서버 관련 정보를 저장하고, 사용자가 해당 서버에 접근할 때마다 그 정보를  함께 전송하게 하는 것이다. 브라우저는 쿠키 정보를 저장할 책임이 있는데, 이 시스템을 '클라이언트 측 상태'라고 한다.

사용자에게 쿠키 할당

 

 

구글 크롬 쿠키

구글 크롬은 Cookies 라는 SQLite 파일에 쿠키를 저장한다.

 

이 SQLite 파일에 있는 각 행이 쿠키 한 개에 해당한다.

 

creation_utc

쿠키가 생성된 시점을 알려주는데, 그 값은 Jan 1, 1970 00:00:00 GMT로부터 생성된 시간을 초 단위로 기술한다.

 

host_key

쿠키의 도메인이다.

 

name 

쿠키의 이름이다.

 

value

쿠키의 값이다.

 

path

쿠키와 관련된 도메인에 있는 경로다.

 

expire_utc

쿠키의 파기 시점을 알려주는데, 그 값은 Jan 1, 1970 00:00:00 GMT로부터 파기될 시간을 초 단위로 기술한다.

 

secure

이 쿠키를 SSL 커넥션일 경우에만 보낼지를 가리킨다.

 

 

쿠키와 캐싱

쿠키 트랜잭션과 관련된 문서를 캐싱하는 것은 주의해야 한다. 이전 사용자의 쿠키가 다른 사용자에게 할당돼버리거나, 누군가의 개인 정보가 다른 이에게 노출되는 최악의 상황이 일어날 수도 있다.

  • 캐시되지 말아야 할 문서가 있다면 표시하라
  • Set-Cookie 헤더를 캐시 하는 것에 유의하라 (같은 Set-Cookie 헤더를 여러 사용자에게 보내면, 사용자 추적에 실패한다.)
  • Cookie 헤더를 가지고 있는 요청을 주의하라

 

쿠키, 보안 그리고 개인정보

 쿠키를 사용하지 않도록 비활성화시킬 수 있고, 로그 분석 같은 다른 방법으로 대체하는 것도 가능하므로, 그 자체가 보안상으로 엄청나게 위험한 것은 아니다. 사실, 원격 데이터베이스에 개인 정보를 저장하고 해당 데이터의 키 값을 쿠키에 저장하는 방식을 표준으로 사용하면, 클라이언트와 서버 사이에 예민한 데이터가 오가는 것을 줄일 수 있다.

 

 

'네트워크' 카테고리의 다른 글

쿠버네티스 네트워크  (0) 2025.04.08
기본 인증  (0) 2024.08.15
캐시  (1) 2024.08.07
웹 서버  (1) 2024.08.06
HTTP 완벽 가이드 - 커넥션 관리(2)  (0) 2024.07.22

+ Recent posts