You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.3 KiB
43 lines
1.3 KiB
import hashlib
|
|
from datetime import datetime
|
|
from fastapi import Request, HTTPException
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from models import FlowApiKey
|
|
from database import get_db
|
|
|
|
|
|
async def authenticate_api_key(request: Request) -> dict:
|
|
auth_header = request.headers.get("Authorization", "")
|
|
if not auth_header.startswith("Bearer "):
|
|
raise HTTPException(401, "缺少认证信息")
|
|
|
|
raw_key = auth_header[7:]
|
|
if not raw_key.startswith("flow-"):
|
|
raise HTTPException(401, "无效的API Key格式")
|
|
|
|
key_hash = hashlib.sha256(raw_key.encode()).hexdigest()
|
|
|
|
db_gen = get_db()
|
|
db: AsyncSession = await db_gen.__anext__()
|
|
try:
|
|
result = await db.execute(
|
|
select(FlowApiKey).where(FlowApiKey.key_hash == key_hash)
|
|
)
|
|
api_key = result.scalar_one_or_none()
|
|
if not api_key:
|
|
raise HTTPException(401, "API Key无效或已删除")
|
|
|
|
api_key.last_used_at = datetime.utcnow()
|
|
await db.flush()
|
|
|
|
return {
|
|
"flow_id": str(api_key.flow_id),
|
|
"api_key_id": str(api_key.id),
|
|
"auth_type": "api_key",
|
|
}
|
|
finally:
|
|
try:
|
|
await db_gen.__anext__()
|
|
except StopAsyncIteration:
|
|
pass
|
|
|