简体   繁体   English

fastapi - 使用 JWT 的 Firebase 身份验证?

[英]fastapi - firebase authentication with JWT's?

I'm trying to use fastapi to return some basic ML models to users.我正在尝试使用 fastapi 将一些基本的 ML 模型返回给用户。

Currently, I secure user details with firebase auth.目前,我使用 firebase auth 保护用户详细信息。 I want to use the JWT's users have when using the basic application to authenticate their request for the ML model.我想在使用基本应用程序时使用 JWT 的用户来验证他们对 ML 模型的请求。

With fastapi, there doesn't seem to be a straightforward answer to doing this.使用 fastapi,这样做似乎没有一个简单的答案。

I've followed two main threads as ways to work out how to do this, but am a bit lost as to how I can simply take the JWT from the header of a request and check it against firebase admin or whathave you?我已经按照两个主要线程来解决如何做到这一点,但是对于如何简单地从请求的标头中获取 JWT 并根据 firebase 管理员或你有什么来检查它有点迷茫?

Following this tutorial and using this package, I end up with something like this, https://github.com/tokusumi/fastapi-cloudauth .按照本教程并使用这个包,我最终得到了类似的东西, https://github.com/tokusumi/fastapi-cloudauth This doesn't really do anything - it doesn't authenticate the JWT for me, bit confused as to if this package is actually worthwhile?这并没有真正做任何事情——它没有为我验证 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}"

Alternatively, looking at this,或者,看着这个,

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

It seems like something like this would work,似乎这样的事情会起作用,

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!"}

But honestly I'm a bit confused about how I would set up the firebase environment variables, what packages I would need (firebaseadmin?)但老实说,我对如何设置 firebase 环境变量、我需要哪些包(firebaseadmin?)有点困惑

Would love some helpers, thanks!想要一些帮手,谢谢!

I hope this will help:我希望这个能帮上忙:

  1. Create functions to work with Firebase admin, create credentials from Firebase as JSON file:创建与 Firebase 管理员一起使用的函数,从 Firebase 创建凭据为 JSON 文件:
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
  1. Then put it inside your FastAPI main function:然后把它放在你的 FastAPI 主函数中:
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']} 

PS Do not forget to install requirements: pip3 install firebase_admin PS不要忘记安装要求: pip3 install firebase_admin

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM