python-3.x 标头和URL中的FastAPI密钥

oyxsuwqo  于 2023-05-13  发布在  Python
关注(0)|答案(1)|浏览(167)

我有一个基于FastAPI的Python3 API,需要验证。我可以在正文中请求API密钥,或者使用Depends作为URL的一部分,如here所述。有没有办法从 * 任何一个 * 来源接受它?
预期的行为是这样的:如果API key在x-api-key头中可用,则返回端点应该返回的任何内容。否则,在URL中查找?api_key=mysecretkey值。如果在那里找到它并且它是有效的,则继续到端点;否则,返回401或403。

lrl1mhuk

lrl1mhuk1#

您通常可以使用FastAPI的依赖关系系统来组合依赖关系,并将逻辑移动到更小的可组合依赖关系中。
要同时接受一个API键作为查询参数和头文件,创建一个允许其中一个的依赖项,两者都是可选的,然后确保至少有一个存在(如果两者都存在,则决定您希望优先给予哪一个):

from fastapi import FastAPI, Depends, Query, Header
from fastapi.exceptions import HTTPException
from typing import Annotated, Optional

app = FastAPI()

users = {
    'random_token': {'id': 1}
}


def token_from_header_or_qs(api_key: str | None = Query(None), x_api_key: str | None = Header(None)) -> str:
    token = api_key or x_api_key
    
    if not token:
        raise HTTPException(status_code=400)
        
    return token
    

def get_current_user(token: Annotated[str, Depends(token_from_header_or_qs)]):
    user = users.get(token)
    
    if not user:
        raise HTTPException(status_code=401)
        
    return user
    
    
@app.get("/")
def protected_endpoint(user: Annotated[dict, Depends(get_current_user)]):
    return user

token_from_header_or_qs函数允许来自任何一个源的令牌,而get_current_user函数只关心验证令牌和获取用户。控制器函数唯一需要关心的是获取有效的用户(如果您希望它们存在于所有或一组路由中,您也可以将这些注册为APIRouter或FastAPI示例本身的依赖项。

相关问题