Files
joke/api/app/routers/auth.py
T
bwstudioandClaude Opus 4.7 c3a8e3e311 feat(api): implement FastAPI routes with JWT authentication
- jokes.py: Public joke listing, detail, and random endpoints
- categories.py: Type and crowd listing endpoints
- auth.py: Login endpoint with JWT token generation
- admin.py: Full CRUD for jokes, types, crowds with JWT protection
- Fix request body schemas to use Create DTOs instead of Response models

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 21:02:59 +08:00

39 lines
1.5 KiB
Python

from datetime import datetime, timedelta, timezone
from fastapi import APIRouter, Depends, HTTPException
from jose import jwt
from passlib.context import CryptContext
from sqlalchemy.orm import Session
from app.config import JWT_ALGORITHM, JWT_EXPIRATION_HOURS, JWT_SECRET_KEY
from app.database import get_db
from app.models.user import AdminUser
from app.schemas.auth import LoginRequest, TokenResponse
router = APIRouter(prefix="/auth", tags=["认证"])
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""验证密码"""
return pwd_context.verify(plain_password, hashed_password)
def create_access_token(data: dict) -> str:
"""创建 JWT token"""
to_encode = data.copy()
expire = datetime.now(timezone.utc) + timedelta(hours=JWT_EXPIRATION_HOURS)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, JWT_SECRET_KEY, algorithm=JWT_ALGORITHM)
return encoded_jwt
@router.post("/login", response_model=TokenResponse)
def login(req: LoginRequest, db: Session = Depends(get_db)):
"""管理员登录"""
user = db.query(AdminUser).filter(AdminUser.username == req.username).first()
if not user or not verify_password(req.password, user.password_hash):
raise HTTPException(status_code=401, detail="用户名或密码错误")
access_token = create_access_token(data={"sub": str(user.id), "username": user.username})
return TokenResponse(access_token=access_token)