Choorai
🔐 고급 주제

사용자 인증 구현

로그인, 회원가입, 비밀번호 관리 등 사용자 인증 기능을 구현합니다. 보안을 고려한 올바른 방법을 배워봅시다.

이 가이드에서 배우는 것

  • 인증 방식 비교 (세션 vs JWT)
  • 비밀번호 해싱 (bcrypt)
  • OAuth 소셜 로그인
  • 인증 서비스 활용 (Clerk, Auth0)

인증 방식 비교

🍪 세션 기반

서버에 세션을 저장하고 쿠키로 세션 ID 전달

  • ✅ 간단한 구현
  • ✅ 즉시 무효화 가능
  • ⚠️ 서버 확장 시 세션 공유 필요

🎫 JWT (토큰 기반)

서명된 토큰을 클라이언트가 보관

  • ✅ 서버 상태 불필요
  • ✅ 마이크로서비스에 적합
  • ⚠️ 토큰 탈취 시 대응 어려움

직접 구현 vs 인증 서비스

권장: 인증 서비스 사용

인증은 보안에 민감한 영역입니다. 처음에는 검증된 인증 서비스를 사용하는 것을 권장합니다.

직접 구현은 보안 취약점을 만들기 쉽고, 유지보수 부담도 큽니다.

추천 인증 서비스

Supabase Auth를 찾으시나요? Supabase 가이드에서 인증 연동 방법을 확인하세요.

FastAPI + JWT 예시 (참고용)

직접 구현해야 한다면, 아래 구조를 참고하세요:

app/auth.py
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta

# 비밀번호 해싱
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# JWT 설정
SECRET_KEY = "your-secret-key"  # 실제로는 환경변수로!
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        user_id: str = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=401, detail="Invalid token")
        return user_id
    except JWTError:
        raise HTTPException(status_code=401, detail="Invalid token")

주의: 프로덕션에서는 더 많은 고려 필요

  • HTTPS 필수
  • 환경변수로 시크릿 키 관리
  • Refresh Token 구현
  • Rate Limiting
  • 로그인 시도 제한

어떤 서비스를 선택할까요?

마지막 업데이트: 2026년 2월 22일 · 버전: v0.0.1

피드백 보내기

입력한 내용으로 새 이슈 페이지를 엽니다.

GitHub 이슈로 보내기