fastapi - JWT을 사용한 firebase authentication

Asked 4 months ago, Updated 4 months ago, 249 views

fastapi를 사용하여 사용자에게 몇 가지 기본 ML 모델을 리턴하려고 합니다.

 

현재 사용자 정보 보안을 위해 firebase auth를 쓰고 있는데요.

기본 애플리케이션을 사용하여 ML 모델에 대한 요청을 인증할 때 JWT의 사용자가 가지고 있는 것을 사용하고 싶습니다.

 

fastapi는 이렇게 하는 것에 대한 간단한 답이 없는 것 같은데요.

이 작업을 수행하는 방법을 찾기 위해 두 main thread를 따랐지만, 요청 헤더에서 JWT를 간단히 추출하여 firebase admin 에게 확인하는 방법이나 다른 방법 같은 것이 있는가 해서요.

 

https://github.com/tokusumi/fastapi-cloudauth

이 튜토리얼을 따라 이 패키지를 사용하면 결과가 제대로 안 나옵니다.

이 패키지가 실제로 일을 하는 것인지 모르겠는데 어쨌든 JWT 인증이 되지 않습니다.

from fastapi import FastAPI, HTTPException, Header,Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims

app = FastAPI()
security = HTTPBearer()


origins = [
    xxxx
]

app.add_middleware(
   xxxx

)

get_current_user = FirebaseCurrentUser(
    project_id=os.environ["PROJECT_ID"]
)


@app.get("/user/")
def secure_user(current_user: FirebaseClaims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.user_id}"

 

 

아니면, 이걸 보면

https://github.com/tiangolo/fastapi/issues/4768

이런 식으로 하면 될 것 같은데

 

security = HTTPBearer()

api = FastAPI()
security = HTTPBearer()

firebase_client = FirebaseClient(
    firebase_admin_credentials_url=firebase_test_admin_credentials_url
    # ...
)

user_roles = [test_role]

async def firebase_authentication(token: HTTPAuthorizationCredentials = Depends(security)) -> dict:
    user = firebase_client.verify_token(token.credentials)
    return user

async def firebase_authorization(user: dict = Depends(firebase_authentication)):
    roles = firebase_client.get_user_roles(user)

    for role in roles:
        if role in user_roles:
            return user

    raise HTTPException(detail="User does not have the required roles", status_code=HTTPStatus.FORBIDDEN)

@api.get("/")
async def root(uid: str = Depends(firebase_authorization)):
    return {"message": "Successfully authenticated & authorized!"}

 

하지만 솔직히 Firebase 환경 변수를 설정하는 방법이라던가 필요한 패키지가 무엇인지에 대해 잘 모르겠습니다.

python firebase firebase-authentication fastapi

2022-05-21 14:57

1 Answers

이렇게 한번 해보세요.

1. Firebase admin으로 사용할 함수 만들기, JSON 파일로 Firebase에서 자격 증명(credential)을 만듭니다.

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends, HTTPException, status, Response
from firebase_admin import auth, credentials, initialize_app

credential = credentials.Certificate('./key.json')
initialize_app(credential)

def get_user_token(res: Response, credential: HTTPAuthorizationCredentials=Depends(HTTPBearer(auto_error=False))):
    if cred is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Bearer authentication is needed",
            headers={'WWW-Authenticate': 'Bearer realm="auth_required"'},
        )
    try:
        decoded_token = auth.verify_id_token(credential.credentials)
    except Exception as err:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Invalid authentication from Firebase. {err}",
            headers={'WWW-Authenticate': 'Bearer error="invalid_token"'},
        )
    res.headers['WWW-Authenticate'] = 'Bearer realm="auth_required"'
    return decoded_token

 

2. 그런 다음 Fast API main 함수에 넣습니다.

from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi import Depends, HTTPException, status, Response, FastAPI, Depends
from firebase_admin import auth, credentials, initialize_app

credential = credentials.Certificate('./key.json')
initialize_app(credential)

def get_user_token(res: Response, credential: HTTPAuthorizationCredentials=Depends(HTTPBearer(auto_error=False))):
    if cred is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Bearer authentication is needed",
            headers={'WWW-Authenticate': 'Bearer realm="auth_required"'},
        )
    try:
        decoded_token = auth.verify_id_token(credential.credentials)
    except Exception as err:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Invalid authentication from Firebase. {err}",
            headers={'WWW-Authenticate': 'Bearer error="invalid_token"'},
        )
    res.headers['WWW-Authenticate'] = 'Bearer realm="auth_required"'
    return decoded_token

app = FastAPI()

@app.get("/api/")
async def hello():
    return {"msg":"Hello, this is API server"} 


@app.get("/api/user_token")
async def hello_user(user = Depends(get_user_token)):
    return {"msg":"Hello, user","uid":user['uid']}

 해보실 때 아래 패키지를 설치하는 것도 필요합니다.

pip3 install firebase_admin


2022-05-21 15:05

If you have any answers or tips


© 2022 pinfo. All rights reserved.