포스트

[FastAPI] <5 : 보안 - 1.기본>

공식 문서

1. 보안이 필요한 이유.

정말 간단한 웹페이지가 아니고서야, 실제 유저를 대상으로 서비스를 할 경우 사용자의 아이디와 패스워드를 통해 유저의 정보를 관리할 것이다.

대부분의 서비스 코드에서 보안은 정말 어렵고 복잡한 주제이고, 많을 경우 전체 코드의 반 이상이 보안에 관련된 코드일 수도 있다.

2. OpenAPI

FastAPI에선 OpenAPI를 기반으로 보안 체계를 정의한다.

  • apiKey : 애플리케이션을 특정하게 해주는 Key. 이하에서 얻어온다.
    • 쿼리
    • 쿠키
    • 헤더
  • http : 표준 http 인증 시스템. 이하 내용을 포함한다.
    • bearer Authorization: Bearer 값에 토큰이 더해진 header. OAuth2에서 상속해온다.
    • HTTP 기본 인증
    • HTTP 다이제스트
  • oauth2 : 보안을 처리하는 OAuth2 방법
  • openIdConnect : OAuth2 인증 데이터를 자동으로 찾아주는 방법

3. Password 흐름

1
2
3
4
5
6
7
8
9
10
11
12
from typing import Annotated

from fastapi import Depends, FastAPI
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.get("/items/")
async def read_items(token: Annotated[str, Depends(oauth2_scheme)]):
    return {"token": token}

다음과 같은 간단한 백엔드 코드가 있고, 실제로 사용자가 password를 입력한다면 어떻게 동작하는지 알아보자.

  1. 사용자가 usernamepassword를 입력한다.
  2. 입력한 usernamepassword 를 프론트엔드에서 API에서 정의한 특정 URL로 보낸다.
  3. API는 token 을 통해 usernamepassword 를 체크한다. (위의 코드엔 아직 정의되지 않음.)
    1. token 은 단순한 문자열이다. 이후에 해당 유저를 검증할때 재사용 가능하다.
    2. 토큰은 일정한 시간이 된다면 만료된다. 만료된다면 유저는 다시 로그인해야한다.
    3. 만료되는것으로, 토큰이 중간에 유출된다 하더라고 어느정도 보안을 지킬 수 있게 된다.
  4. 프론트엔드에선 발급된 토큰을 일시적으로 저장한다.

3.1 FastAPI의 OAuth2PasswordBearer

FastAPI에선 OAuth2PasswordBearer 를 통해 Bearer 토큰을 사용해 비밀번호와 OAuth2를 사용 가능하다.

1
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

이후 실제로 token을 받아올 장소에서 Depends를 사용해 token을 전달해 줄 수 있다.

1
2
3
@app.get("/items/")
async def read_items(token: Annotated[str, Depends(oauth2_scheme)]):
    return {"token": token}

token은 문자열이며, Depends를 통해 반드시 oauth2_scheme를 통과해야만 한다.

4. 예외

만약 토큰이 존재하지 않거나, 잘못된 토큰을 가져온다면 401(UNAUTHORIZED) 예외를 내놓는다.

해당 예외는 Swagger 문서에서 바로 확인 가능하다.

아직 아무것도 없기 때문에 Execute를 하면 해당 예외를 발생시킬 수 있다.



이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.