重构UniversalAPIManager以支持Dify工作流API 添加DifyWorkflowRequest模型和控制器方法 优化API密钥管理和请求处理逻辑 修改JWT验证方式从HTTPBearer到Header 更新API配置以支持新的Dify端点
83 lines
2.3 KiB
Python
83 lines
2.3 KiB
Python
from datetime import datetime, timedelta
|
|
from typing import Optional
|
|
import jwt
|
|
from fastapi import HTTPException, status, Depends, Header
|
|
from app.controllers.app_user import app_user_controller
|
|
from app.schemas.app_user import AppUserJWTPayload
|
|
from app.settings import settings
|
|
|
|
# JWT配置
|
|
SECRET_KEY = settings.SECRET_KEY
|
|
ALGORITHM = "HS256"
|
|
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 # 7天
|
|
|
|
|
|
def create_app_user_access_token(user_id: int, phone: str) -> str:
|
|
"""
|
|
为AppUser创建访问令牌
|
|
"""
|
|
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
|
|
to_encode = {
|
|
"user_id": user_id,
|
|
"phone": phone,
|
|
"exp": expire
|
|
}
|
|
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
|
return encoded_jwt
|
|
|
|
|
|
def verify_app_user_token(token: str) -> Optional[AppUserJWTPayload]:
|
|
"""
|
|
验证AppUser令牌
|
|
"""
|
|
try:
|
|
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
|
user_id: int = payload.get("user_id")
|
|
phone: str = payload.get("phone")
|
|
exp: datetime = datetime.fromtimestamp(payload.get("exp"))
|
|
|
|
if user_id is None or phone is None:
|
|
return None
|
|
|
|
return AppUserJWTPayload(user_id=user_id, phone=phone, exp=exp)
|
|
except jwt.DecodeError:
|
|
return None
|
|
except jwt.ExpiredSignatureError:
|
|
return None
|
|
except Exception:
|
|
return None
|
|
|
|
|
|
def get_current_app_user_id(token: str = Header(None)) -> int:
|
|
"""
|
|
从令牌中获取当前AppUser ID
|
|
"""
|
|
credentials_exception = HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="无效的认证凭据",
|
|
headers={"WWW-Authenticate": "Bearer"},
|
|
)
|
|
|
|
if not token:
|
|
raise credentials_exception
|
|
|
|
payload = verify_app_user_token(token)
|
|
if payload is None:
|
|
raise credentials_exception
|
|
|
|
return payload.user_id
|
|
|
|
|
|
async def get_current_app_user(
|
|
current_user_id: int = Depends(get_current_app_user_id)
|
|
):
|
|
"""
|
|
获取当前AppUser
|
|
"""
|
|
user = await app_user_controller.get_user_by_id(current_user_id)
|
|
if user is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="用户不存在或已被停用"
|
|
)
|
|
return user |