Files
guzhujushiBlog/backend/routers/deps.py
T

41 lines
1.6 KiB
Python

"""
路由公共依赖。
提供“可选登录”依赖与权限判断工具:
- 文章可见性控制需要区分“游客”和“登录用户”
- 携带有效令牌时返回用户,未携带令牌时返回 None
"""
from typing import Optional
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from ..auth import bearer_scheme, decode_token
from ..database import get_db
from ..models import ROLE_BLOGGER, ROLE_FRIEND, User
def get_optional_user(
credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
db: Session = Depends(get_db),
) -> Optional[User]:
"""可选登录依赖:未携带令牌返回 None;令牌无效返回 401;否则返回当前用户。"""
if credentials is None:
return None
payload = decode_token(credentials.credentials)
try:
user_id = int(payload.get("sub"))
except (TypeError, ValueError):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="令牌无效")
user = db.query(User).filter(User.id == user_id).first()
# 令牌版本校验:与 get_current_user 保持一致,密码重置后旧令牌失效
if user is not None and (payload.get("ver") or 0) != (user.token_version or 0):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="登录状态已失效,请重新登录")
return user
def can_read_friend_article(user: Optional[User]) -> bool:
"""判断用户是否具备查看好友文章的权限(friend / blogger)。"""
return user is not None and user.role in (ROLE_FRIEND, ROLE_BLOGGER)