[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를 입력한다면 어떻게 동작하는지 알아보자.
- 사용자가
username
과password
를 입력한다. - 입력한
username
과password
를 프론트엔드에서 API에서 정의한 특정 URL로 보낸다. - API는
token
을 통해username
과password
를 체크한다. (위의 코드엔 아직 정의되지 않음.)token
은 단순한 문자열이다. 이후에 해당 유저를 검증할때 재사용 가능하다.- 토큰은 일정한 시간이 된다면 만료된다. 만료된다면 유저는 다시 로그인해야한다.
- 만료되는것으로, 토큰이 중간에 유출된다 하더라고 어느정도 보안을 지킬 수 있게 된다.
- 프론트엔드에선 발급된 토큰을 일시적으로 저장한다.
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를 하면 해당 예외를 발생시킬 수 있다.