guzhi/app/utils/app_user_jwt.py
邹方成 107e90cbcb feat(third_party_api): 添加Dify工作流支持并优化API管理
重构UniversalAPIManager以支持Dify工作流API
添加DifyWorkflowRequest模型和控制器方法
优化API密钥管理和请求处理逻辑
修改JWT验证方式从HTTPBearer到Header
更新API配置以支持新的Dify端点
2025-10-10 13:04:10 +08:00

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