fastapi - JWT을 사용한 firebase authentication

1개월 전 질문 1개월 전 토론 39 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개의 해답

이렇게 한번 해보세요.

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

해결방법이나 팁을 알고 계신다면


© 2022 pinfo. All rights reserved.