"""认证 API:POST /auth/login、POST /auth/register、GET /auth/me""" from typing import Any import structlog from fastapi import APIRouter, Depends from app.api.response import ApiError, ok from app.config import settings from app.core.auth import ( ERR_REGISTER_DISABLED, UserStore, create_access_token, get_current_user, get_user_store, ) from app.models.auth import ( AuthUser, LoginRequest, RegisterRequest, TokenResponse, ) logger = structlog.get_logger() router = APIRouter(prefix="/api/v1", tags=["auth"]) def _build_token_response(user, store: UserStore) -> dict[str, Any]: """签发 token 并构造统一响应 data""" token, expires_in = create_access_token(user.username, user.role) auth_user = AuthUser(username=user.username, role=user.role, created_at=user.created_at) resp = TokenResponse(access_token=token, expires_in=expires_in, user=auth_user) return resp.model_dump(mode="json") @router.post("/auth/login") async def login(req: LoginRequest) -> dict[str, Any]: """用户名密码登录,返回 JWT access_token""" store = get_user_store() user = await store.authenticate(req.username, req.password) logger.info("用户登录成功", username=user.username) return ok(_build_token_response(user, store)) @router.post("/auth/register") async def register(req: RegisterRequest) -> dict[str, Any]: """注册新用户(role=user),注册后自动签发 token 受 settings.auth_register_enabled 控制,关闭时返回 ERR_REGISTER_DISABLED。 """ if not settings.auth_register_enabled: raise ApiError(ERR_REGISTER_DISABLED, "注册已关闭") store = get_user_store() user = await store.create(req.username, req.password, role="user") return ok(_build_token_response(user, store)) @router.get("/auth/me") async def me(user: AuthUser = Depends(get_current_user)) -> dict[str, Any]: """返回当前登录用户信息""" return ok(user.model_dump(mode="json"))