본문 바로가기
Python/FastAPI

[FastAPI] 스웨거(Swagger) `OAuth2 인증 Authorize 적용`하기

by 검은냥냥이 2022. 12. 12.

스웨거에서 `OAuth2` 방식으로 인증 방식을 사용할 수 있습니다. `OAuth2` 인증을 달게 되면, 스웨거에서 `Authorize`라는 버튼이 생기게 되며, 해당 버튼을 통해서 `OAuth2 인증`을 할 수 있습니다.

인증이 필요한 API가 있기 때문에, 작업을 미리 해두면 편합니다.

 

Oauth2 적용하기

`home.py`

아래와 같이 `APIRouter`에서 `dependencies`를 추가해주고, `tokenUrl`을 넣어주면 된다.

참고로 `tokenUrl`은 `root_path`가 먹히지 않기 때문에 앞에 들어가는 경로를 모두 넣어주어야 한다.

router = APIRouter(
    prefix="/home",
    tags=["home"],
    dependencies=[
        Depends(
            OAuth2PasswordBearer(
                tokenUrl="/api/v1/token",
                description="인증이 필요한 API를 호출하기 위해 로그인 해주세요",
                # scopes={}
            ),
        ),
    ],
    responses={404: {"description": "Not found"}}
)

@router.post("/", tags=["home"], responses=home_argument.HomeRead)
@router.post("", tags=["home"], include_in_schema=False)
async def HomeRead(
        credentials: HTTPBasicCredentials = Depends(security),
):
	# 로직 처리
    banner = banner_crud.BannerRead(limit=5, db=db)
    feed = feed_crud.FeedRead(limit=5, db=db)
    
	return JSONResponse(status_code=200, content={
		"status_code": status.HTTP_200_OK,
        "data": {
        	"banner": jsonable_encoder(banner),
            "feed": jsonable_encoder(banner),
		}
	})

 

`token.py`

아래는 위에서 설정한 `tokenUrl`를 처리하는 API 입니다.

함수에 `OAuth2PasswordRequestFormStrict = Depends()`를 추가하여, 스키마를 받을 수 있습니다.

기본적으로 `grant_type`, `username`, `password`, `scope`, `client_id`, `client_secret`가 있지만, 모두 필수는 아닙니다.

그리고 주의할 점은 리턴 데이터를 아래와 같이 양식을 맞춰야 됩니다.

router = APIRouter(
    prefix="/token",
    tags=["token"],
    responses={404: {"description": "Not found"}}
)


@router.post("/", tags=["token"], responses=token_argument.TokenRead)
@router.post("", tags=["token"], include_in_schema=False)
async def TokenRead(
        req: Request,
        schemas: OAuth2PasswordRequestFormStrict = Depends(),
        authorize: AuthJWT = Depends(),
        db: Session = Depends(handleDataBase)
):
    """
    스웨거 전용 토큰 조회
    \f
    :param req: Request
    :param schemas: Form Data
    :param authorize: JWT Token
    :param db: DataBase Session
    """
	
    # 유저 조회
    user = db.query(models.User) \
        .filter(models.User.email == schemas.username) \
        .first()

	# 정상적인 유저인지
    if user is False:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid User",
            headers={"WWW-Authenticate": "Bearer"},
        )

	# 비밀번호는 유효한지
    if pbkdf2_sha256.verify(schemas.password, user.password) is False:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid Password",
            headers={"WWW-Authenticate": "Bearer"},
        )

	# 개별적으로 넣은 권한
    if user.is_status == 0:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid Access",
            headers={"WWW-Authenticate": "Bearer"},
        )

    return JSONResponse(status_code=200, content={
        "access_token": authorize.create_access_token(subject=user.idx).encode().decode('UTF-8'),
        "token_type": "bearer"
    })

 

참고 링크

 

Security - First Steps - FastAPI

Security - First Steps Let's imagine that you have your backend API in some domain. And you have a frontend in another domain or in a different path of the same domain (or in a mobile application). And you want to have a way for the frontend to authenticat

fastapi.tiangolo.com

 

728x90
사업자 정보 표시
레플라 | 홍대기 | 경기도 부천시 부일로 519 화신오피스텔 1404호 | 사업자 등록번호 : 726-04-01977 | TEL : 070-8800-6071 | Mail : support@reafla.co.kr | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기