Files
PlantAI-rag-new/sdk/app/routers/auth.py
T

53 lines
1.8 KiB
Python

"""routers/auth.py —— 用户端鉴权端点(登录/登出/me/status)。"""
from __future__ import annotations
from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from ..auth import require_user
from ..config import get_settings
from ..db import Database, get_db
from ..logwriter import log_event
from ..services.auth import verify_login, issue_token, revoke_token
from ..upstream import envelope
router = APIRouter(prefix="/api/auth", tags=["auth"])
class LoginBody(BaseModel):
username: str
password: str
@router.get("/status")
async def status():
"""免鉴权:告知前端是否开启鉴权(决定是否显示登录页)。"""
return {"ok": True, "auth_enabled": get_settings().auth_enabled}
@router.post("/login")
async def login(body: LoginBody, db: Database = Depends(get_db)):
user = await verify_login(db, body.username, body.password)
if user is None:
log_event("login_fail", detail={"username": body.username})
content, status = envelope("UNAUTHORIZED", "用户名或密码错误", status=401)
return JSONResponse(status_code=status, content=content)
token = await issue_token(db, user["id"], ttl_seconds=get_settings().user_token_ttl_seconds)
log_event("login_ok", user_id=user["id"], detail={"username": body.username})
return {"ok": True, "token": token, "user": user}
@router.post("/logout")
async def logout(request: Request, db: Database = Depends(get_db), _user: dict = Depends(require_user)):
header = request.headers.get("Authorization", "")
token = header[7:] if header.startswith("Bearer ") else ""
if token:
await revoke_token(db, token)
return {"ok": True}
@router.get("/me")
async def me(_user: dict = Depends(require_user)):
return {"ok": True, "user": _user}