[한컴AI 아카데미 | 2026.06.11 | Day 73] FastAPI ② - Cookie, Session, JWT 인증 구현 및 비교

2026. 6. 11. 22:19·부트캠프

1. Cookie Authentication (쿠키 인증 방식)

가장 원초적인 인증 방식으로, 서버가 사용자 식별 정보(데이터)를 브라우저의 쿠키에 직접 저장하는 방식이다.

💻 코드 핵심 구현

로그인 (/login): 인증 성공 시 response.set_cookie를 통해 평문 username을 쿠키에 설정한다.

response.set_cookie(key="user_session", value=username, httponly=True)

인증 확인 (/me): FastAPI의 Cookie(None) 매개변수를 통해 브라우저가 자동으로 보낸 쿠키 값을 읽어 DB에서 사용자를 조회한다.

async def get_me(user_session: str | None = Cookie(None), db=Depends(get_db)):

로그아웃 (/logout): response.delete_cookie로 브라우저의 쿠키를 강제 삭제한다.

💡 코드 분석 피드백

보안 위험성: 코드에서 보듯 value=username 형태로 사용자의 식별 정보가 브라우저에 평문으로 노출된다.
사용자가 쿠키 값을 조작(user_session=admin)하여 다른 사람으로 위장할 수 있는 치명적인 약점이 존재한다.

2. Session Authentication (세션 인증 방식)

쿠키 인증의 보안 문제를 해결하기 위해, 사용자의 실제 정보는 서버(DB)에 안전하게 저장하고 브라우저에는 임의의 랜덤 문자열(Session ID)만 전달하는 방식이다.

💻 코드 핵심 구현

세션 테이블 구성: sessions 테이블을 만들어 ID와 유저명을 매핑한다.

CREATE TABLE IF NOT EXISTS sessions (session_id TEXT PRIMARY KEY, username TEXT NOT NULL)

로그인 (/login): uuid.uuid4()로 예측 불가능한 고유 ID를 생성하여 DB에 저장하고, 브라우저에는 유저명 대신 이 session_id만 쿠키로 만든다.

session_id = str(uuid.uuid4())
await db.execute("INSERT INTO sessions (session_id, username) VALUES (?, ?)", (session_id, username))
response.set_cookie(key="session_id", value=session_id, httponly=True)

 

• 인증 확인 (/me): 쿠키로 받아온 session_id가 세션 테이블에 존재하는지 확인하고 유저명을 꺼내온다.

• 로그아웃 (/logout): 브라우저의 쿠키를 지울 뿐만 아니라, 서버 DB에서도 세션 데이터를 삭제(DELETE FROM sessions...)하여 토큰을 무효화한다.

💡 코드 분석 피드백

보안성은 크게 향상되었지만, 매 요청마다 sessions 테이블을 조회해야 하므로
DB 인프라 비용이 증가하고 다중 서버 환경에서 세션 동기화 문제가 발생할 수 있다.


3. JWT Authentication (JSON Web Token 인증 방식)

서버의 세션 저장소 부담을 없애기 위해 등장한 Stateless(상태를 저장하지 않는) 인증 방식이다.

정보를 토큰 자체에 암호화(서명)하여 들고 다닌다.

💻 코드 핵심 구현

토큰 생성 (create_access_token): RFC 7519 규격에 맞춰 유저 정보(sub)와 만료 시간(exp)을 담고, 서버만 아는 SECRET_KEY와 HS256 알고리즘으로 서명(Encode)한다.

def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
    ...
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

 

로그인 (/login): 성공 시 쿠키가 아닌 JSON 바디로 토큰을 반환한다.

return {"access_token": access_token, "token_type": "bearer"}

인증 확인 (/me): FastAPI의 의존성 주입(Depends)과 OAuth2PasswordBearer를 사용하여,

요청 헤더(Authorization: Bearer <TOKEN>)에서 토큰을 추출하고 검증(Decode)한다.

payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")

4. JWT + Frontend(jQuery) 연동 및 FastAPI Depends 활용

마지막 코드(05_jwt2.py)는 전형적인 현대적인 웹 애플리케이션(SPA 스타일)의 API 서버 패턴을 보여준다.

💻 코드 핵심 구현

Pydantic 모델 도입: 폼 데이터(Form(...)) 대신 JSON 바디 기반의 통신을 위해 UserCreate, UserLogin 형식을 정의다.

class UserLogin(BaseModel):
    username: str
    password: str

정적 파일 서빙: 프론트엔드 파일(HTML, JS, CSS)을 백엔드에서 서빙할 수 있도록 마운트했다.

app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")

의존성 주입 분리 (get_current_user): 인증 로직을 독립된 함수로 분리하여 코드의 재사용성을 극대화했다.

# 독립된 인증 함수
async def get_current_user(token: str = Depends(oauth2_scheme), db=Depends(get_db)):
    ...
    return user["username"]

# 필요한 엔드포인트에서 주입하여 사용
@app.get("/me")
async def get_me(current_user: str = Depends(get_current_user)):
    return {"username": current_user}
💡 프론트엔드(jQuery) 동작 원리 매핑

로그인 시: 위 API가 주는 access_token을 받아 브라우저의 localStorage.setItem("access_token", ...)으로 저장한다.
인증이 필요한 API 호출 시: jQuery $.ajax 요청 시 헤더에 Authorization: 'Bearer ' + token을 담아 보낸다.
백엔드의 oauth2_scheme가 이 헤더를 감지하여 유효성을 검사하게 된다.

메무아

이번 실습을 통해 Cookie, Session, JWT 인증 방식이 단순히 다른 기술이 아니라 각각 이전 방식의 한계를 보완하며 발전해왔다는 점을 이해할 수 있었다. 특히 JWT를 직접 구현하면서 서버가 상태를 저장하지 않고도 인증을 처리하는 방식을 경험할 수 있었고, FastAPI의 Depends()를 활용한 인증 구조도 학습할 수 있었다.

 

다만 현재 구현한 JWT는 Access Token만 사용하는 구조이기 때문에 토큰 만료 시 재로그인이 필요하다는 한계가 있다. 다음에는 Refresh Token을 추가하여 Access Token + Refresh Token 구조를 구현해보며 보다 실무적인 인증 시스템을 경험해보고 싶다.

 

 

 

 

더보기

————————————————————————————————————————————————————— 

 

본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리]

한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.

'부트캠프' 카테고리의 다른 글

[한컴AI 아카데미 | 2026.06.16 | Day 78] 데이터 분석 ② - Matplotlib로 포켓몬 데이터 시각화해보기  (0) 2026.06.17
[한컴AI 아카데미 | 2026.06.15 | Day 77] 데이터 분석 ① - Numpy  (0) 2026.06.16
[한컴AI 아카데미 | 2026.06.09 | Day 71] 크롤링 ③ - BeautifulSoup으로 안 되던 데이터, Selenium 없이 수집할 수 있었던 이유  (0) 2026.06.09
[한컴AI 아카데미 | 2026.06.08 | Day 70] 크롤링 ② - BeautifulSoup과 Selenium  (0) 2026.06.09
[한컴AI 아카데미 | 2026.06.04 | Day 66] 크롤링 ① - urllib와 requests  (0) 2026.06.04
'부트캠프' 카테고리의 다른 글
  • [한컴AI 아카데미 | 2026.06.16 | Day 78] 데이터 분석 ② - Matplotlib로 포켓몬 데이터 시각화해보기
  • [한컴AI 아카데미 | 2026.06.15 | Day 77] 데이터 분석 ① - Numpy
  • [한컴AI 아카데미 | 2026.06.09 | Day 71] 크롤링 ③ - BeautifulSoup으로 안 되던 데이터, Selenium 없이 수집할 수 있었던 이유
  • [한컴AI 아카데미 | 2026.06.08 | Day 70] 크롤링 ② - BeautifulSoup과 Selenium
NGC463l
NGC463l
무한한 우주에서 헤엄치는 고래 한 마리
  • NGC463l
    고래별
    NGC463l
  • 전체
    오늘
    어제
    • 🚀 (66) N
      • 부트캠프 (56) N
      • CS (3)
      • 코딩 테스트 (2)
        • 백준 (1)
      • 프로젝트 (4)
        • 크보패스 (4)
      • 일상 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    LLM
    프로젝트
    개발자교육
    개발자취업
    부트캠프
    백엔드
    한국생산성본부
    한글과컴퓨터
    ai전문가양성
    데이터전처리
    이것이코딩테스트다
    fastapi
    크롤링
    알고리즘
    API연동
    ai개발자교육
    코딩테스트
    TCP
    AI아카데미
    위치기반서비스
    kakaoapi
    이코테
    BFS
    selenium
    PYTHON
    스나이퍼팩토리
    한컴ai아카데미
    AI개발자
    UDP
    컴퓨터네트워크
  • hELLO· Designed By정상우.v4.10.6
NGC463l
[한컴AI 아카데미 | 2026.06.11 | Day 73] FastAPI ② - Cookie, Session, JWT 인증 구현 및 비교
상단으로

티스토리툴바