진취적 삶
7 보안 본문
인증을 거치치 않은 사용자도 이벤트 플래너 애플리케이션을 사용해서 이벤트를 생성할수 있는 문제
인증: 개체가 전달한 인증 정보를 검증하는 것
허가: 객체가 특정 처리를 할수 있도록 권한을 주는 것
7.1 FastAPI 의 인증 방식
기본 HTTP 인증
사용자 인증 정보를 Authorization HTTP 헤더를 사용해 전송하는 방식
쿠키
데이터를 클라이언트 측에 저장할때 사용 FastAPI 애플리케이션도 쿠키를 사용해서 사용자 정보를 저장할수 있으며 서버는 이 정보를 추출해 인증 처리에 사용한다.
bearer 토큰 인증
보안 토큰을 사용해 인증하는 방식 .
가장 많이 사용되는 토큰은 JWT 사용자 ID와 토큰 만료 기간으로 구성된 딕셔너리 형식이 일반적
의존성 주입
객체가 실행에 필요한 인스턴스 변수를 받는 방식을 의미한다.
의존성 주입은 반복된 코드 작성을 줄여주므로 인증과 허가처럼 반복적인 구현이 필요한 경우에 큰도움이 된다.
7.2 OAuth2 와 JWT를 사용한 애플리케이션 보안
액세스 토큰 생성과 검증
JWT는 서버와 클라이언트만 아는 비밀키를 사용해 사인
import time
from database import datetime
from fastapi import HTTPException ,status
from jose import jwt,JWTError
from database.connection import Settings
settings =Settings()
def create_access_token(user:str):
payload={
"user":user,
"expires": time.time()+3600
}
token = jwt.encode(payload,settings.SECRET_KEY , algorithm="HS256")
return token
토큰 생성 함수는 문자열 하나를 받아서 payload 딕셔너리에 전달한다.
payload 딕셔너리는 사용자명과 만료시간을 포함하여 JWT가 디코딩 될때 반환 된다.
encode()
- 페이로드 : 값이 저장된 딕셔너리로, 인코딩할 대상
- 키 : 페이로드를 사인하기 위한 키다
- 알고리즘: 페이로드를 사인 및 암호화 하는 알고리즘 , 기본값이 HS256
from fastapi import Depends,HTTPException,status
from fastapi.security import OAuth2PasswordBearer
from auth.jwt_handler import verify_access_token
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/user/signin")
async def authenticate(token:str = Depends(oauth2_scheme))->str:
if not token:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail = "sign in for access"
)
decoded_token = verify_access_token(token)
return decoded_token["user"]
- depends : oauth2_scheme를 의존 라이브러리 함수에 주입
- OAuth2PasswordBearer : 보안 로직이 존재한다는 것을 애플리케이션에 알려준다.
- verify_access_token : 앞서 정의한 토큰 생성 및 검증함수로, 토큰의 유효성을 확인하다.
이벤트 라우트 변경
from auth.authenticate import authenticate
을 통해서 의존성 주입을 한다.
- POST 라우트 : 생성된 이벤트를 사용자가 소유한 이벤트 목록에 추가한다.
- UPDATE 라우트 : 사용자가 만든 이벤트만 변경할수 있게 한다
- DELETE 라우트 : 사용자가 만들 이벤트만 삭제할수 있게 한다.
7.4 CORS 설정
교차 출처 리소스 공유는 등록되지 않은 사용자가 리소스를 사용하지 못하도록 제한하는 규칙
API 와 출처가 동일한 경우 API가 허가한 출처만 리소스에 접근할수 있다.
CORSMiddleware 라는 CORS 미들웨어를 통해 API에 접근 가능한 출처를 관리한다.