[FastAPI] 🔭 OAuth2 Scopes

2025. 8. 10. 14:31·Python Framework/FastAPI

목차


     

    FastAPI는 Python 기반의 최신 웹 프레임워크로, 속도와 직관성을 동시에 제공하는 것으로 유명한 프레임워크이다.
    그중에서도 OAuth2 Scopes 기능은 보안과 권한 관리에서 매우 중요한 역할을 한다.

     

    OAuth2 Scopes란?

    OAuth2 Scopes는 "누가 무엇을 할 수 있는지"를 세분화해서 정의하는 권한 단위이다.
    즉, 단순히 "로그인 성공"만으로 모든 API 접근을 허용하는 것이 아니라,
    각 API 엔드포인트마다 세부 권한을 지정할 수 있게 해주는 개념이다.

    예시:

    • users:read → 사용자 정보를 읽을 수 있는 권한
    • users:write → 사용자 정보를 수정할 수 있는 권한
    • items → 아이템 데이터를 읽는 권한
    • Google API 예시: https://www.googleapis.com/auth/drive

     

    이렇게 스코프를 정의하면, 토큰이 어떤 스코프를 포함하느냐에 따라 접근을 제어할 수 있다.

    FastAPI에서 OAuth2 Scopes 정의하기

    FastAPI에서는 OAuth2PasswordBearer를 사용할 때 scopes 매개변수를 통해 스코프를 정의한다.

     

    from fastapi.security import OAuth2PasswordBearer
    
    oauth2_scheme = OAuth2PasswordBearer(
        tokenUrl="token",
        scopes={
            "me": "Read information about the current user.",
            "items": "Read items."
        },
    )

     

    여기서 scopes 딕셔너리의 key는 스코프 이름, value는 설명이다.
    이 정보는 OpenAPI 문서에도 반영되어 Swagger UI에서 확인할 수 있다.

    스코프 검증 로직 작성하기

    스코프 검증은 보통 사용자 인증 단계에서 수행된다.
    FastAPI는 SecurityScopes 객체를 통해 요청된 경로에 필요한 스코프 목록을 제공한다.

     

    from fastapi import Depends, HTTPException, status, Security
    from fastapi.security import SecurityScopes
    
    async def get_current_user(
        security_scopes: SecurityScopes,
        token: str = Depends(oauth2_scheme)
    ):
        # 필요한 스코프 문자열 구성 (예: Bearer scope="me items")
        if security_scopes.scopes:
            authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
        else:
            authenticate_value = "Bearer"
    
        credentials_exception = HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": authenticate_value},
        )
    
        # 여기서 JWT 토큰 검증 및 사용자 조회 로직 실행
        user = fake_decode_token(token)
    
        # 사용자 또는 스코프 검증 실패 시 예외 발생
        for scope in security_scopes.scopes:
            if scope not in user.scopes:
                raise credentials_exception
    
        return user

     

    여기서 중요한 점은 다음과 같다.

    • security_scopes.scopes → 경로에서 요구한 스코프 목록
    • 토큰에 포함된 스코프와 비교하여 부족하면 401 에러를 발생시킨다.

    경로별 스코프 지정하기

    FastAPI는 Security()를 사용해 엔드포인트마다 요구 스코프를 선언할 수 있다.

     

    from fastapi import APIRouter, Security
    
    @app.get("/users/me")
    async def read_users_me(
        current_user = Security(get_current_user, scopes=["me"])
    ):
        return current_user
    
    @app.get("/users/me/items")
    async def read_own_items(
        current_user = Security(get_current_user, scopes=["items"])
    ):
        return [{"item_id": "Foo", "owner": current_user.username}]

     

    • /users/me → me 스코프 필요
    • /users/me/items → items 스코프 필요

    이렇게 하면 경로별로 접근 제어를 정밀하게 설정할 수 있다.

    실제 인증 흐름 예시

    1. 로그인 요청
      • 클라이언트가 아이디/비밀번호로 /token 엔드포인트에 로그인 요청
      • 요청 시 필요한 스코프를 함께 요청 (scope=me items)
    2. 토큰 발급
      • 서버는 해당 스코프를 포함한 JWT 액세스 토큰 발급
    3. API 호출
      • 클라이언트가 Authorization 헤더(Bearer <token>)로 API 호출
    4. 스코프 검증
      • FastAPI가 엔드포인트에 필요한 스코프와 토큰의 스코프를 비교
    5. 허용 또는 거부
      • 스코프가 모두 충족되면 응답, 아니면 401 Unauthorized

    장점

    • 보안 강화: 불필요한 권한을 최소화 (최소 권한 원칙)
    • API 문서 자동화: OpenAPI/Swagger UI에서 스코프를 명확히 표시
    • 확장성: 권한 구조를 계층적으로 설계 가능

    마무리

    OAuth2 Scopes는 처음에는 조금 복잡하게 느껴질 수 있지만, 한 번 구조를 잡아두면 API 보안 설계가 훨씬 깔끔해진다.
    FastAPI는 이를 매우 직관적인 방식으로 지원하므로, 보안이 중요한 서비스라면 꼭 적용해보는 것을 추천한다.

    'Python Framework > FastAPI' 카테고리의 다른 글

    [FastAPI] 📌 BackgroundTasks vs Celery — 언제 뭐 쓰면 좋을까?  (5) 2025.08.15
    [FastAPI] 🔐 JWT 로그인 구현하기  (8) 2025.08.07
    'Python Framework/FastAPI' 카테고리의 다른 글
    • [FastAPI] 📌 BackgroundTasks vs Celery — 언제 뭐 쓰면 좋을까?
    • [FastAPI] 🔐 JWT 로그인 구현하기
    Log Cat
    Log Cat
    잊어버리지 않기 위한 메모장
    • Log Cat
      개발 메모장
      Log Cat
    • 전체
      오늘
      어제
      • 전체보기 (45) N
        • Book Review (6)
        • Language (15) N
          • Java (10) N
          • Go (1)
          • JavaScript (1)
          • TypeScript (3)
        • Computer Science (3)
          • Network (1)
          • Database (1)
          • Design Pattern (0)
        • Spring Framework (10)
          • Spring & Spring Boot (4)
          • Spring Batch (4)
          • Servlet & JSP (2)
        • Python Framework (3)
          • FastAPI (3)
        • Infra (3)
          • Dcoker (1)
          • Kafka (2)
        • ORM (1)
          • JPA (1)
        • Fun (1) N
        • Error (2)
        • Retrospective (0)
        • Certificate (1)
    • 블로그 메뉴

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

      • Github
    • 인기 글

    • 태그

      Typescript
      네트워크
      spring
      spring boot
      프로그래머스
      코테
      Python
      백준
      프로그래머스문제
      fastapi
      effective java 3/e
      leetcode
      escape-analysis
      프로그래머스 문제
      Java
      이팩티브 자바
      개발서적
      spring kafka
      자바 풀이
      programmers
      BOJ
      코딩테스트
      성공과 실패를 결정하는 1%의 네트워크 원리
      네트워크 원리
      자바
      jmm
      우아한테크코스
      리트코드
      jvm
      개발서적리뷰
    • 최근 글

    • hELLO· Designed By정상우.v4.10.6
    Log Cat
    [FastAPI] 🔭 OAuth2 Scopes
    상단으로

    티스토리툴바