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

标签 python firebase firebase-authentication fastapi

我正在尝试使用 fastapi 将一些基本的 ML 模型返回给用户。

目前,我使用 firebase auth 保护用户详细信息。我想在使用基本应用程序时使用 JWT 的用户来验证他们对 ML 模型的请求。

使用 fastapi,似乎没有直接的答案。

我已经遵循了两个主要线程来解决如何做到这一点,但是对于如何简单地从请求的 header 中获取 JWT 并根据 firebase 管理员或你有什么检查它有点迷茫?

按照本教程并使用这个包,我最终得到了这样的东西, 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 环境变量、需要哪些包(firebaseadmin?)有点困惑

希望得到一些帮助,谢谢!

最佳答案

我希望这会有所帮助:

  1. 创建与 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. 然后将其放入您的 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']} 

附:不要忘记安装要求: pip3 install firebase_admin

关于python - fastapi - 使用 JWT 的 Firebase 身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72200552/

相关文章:

python - 按模型创建记录

python 继承。为什么这么乱?

javascript - 从 child 的 child 那里获取值(value)

android - 使用 diskpersistence 时有时不会触发 Firebase setValue() 方法

firebase-authentication - Firebase Cloud Messaging Auth token 与注册 token

regex - Cloud Firestore 身份验证正则表达式

firebase - currentUser() 会返回匿名用户 Firebase 吗?

python - 无法使用python通过cronjob重新启动鱿鱼

javascript - 如何从 Firebase 快照返回数组

python - Spyder,位于远程服务器上的运行脚本