61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
"""Auth:登录 / 刷新 / me / 登出。"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from app.core.deps import CurrentUser, DbDep
|
|
from app.core.exceptions import ok
|
|
from app.schemas.auth import (
|
|
LoginRequest,
|
|
MeResponse,
|
|
RefreshRequest,
|
|
RoleBrief,
|
|
TokenPair,
|
|
UserInfo,
|
|
)
|
|
from app.services import auth_service
|
|
from app.services.rbac_service import build_menu_tree, get_user_menus, get_user_perm_codes
|
|
|
|
router = APIRouter(prefix="/auth", tags=["auth"])
|
|
|
|
|
|
@router.post("/login")
|
|
async def login(body: LoginRequest, db: DbDep) -> dict:
|
|
_user, pair = await auth_service.login(db, body.username, body.password)
|
|
return ok(pair.model_dump())
|
|
|
|
|
|
@router.post("/refresh")
|
|
async def refresh(body: RefreshRequest, db: DbDep) -> dict:
|
|
pair: TokenPair = await auth_service.refresh(db, body.refresh_token)
|
|
return ok(pair.model_dump())
|
|
|
|
|
|
@router.post("/logout")
|
|
async def logout(_user: CurrentUser) -> dict:
|
|
# P2:无状态 JWT,客户端清本地 token 即可。
|
|
# 未来可在 Redis 建 denylist 实现服务端吊销。
|
|
return ok()
|
|
|
|
|
|
@router.get("/me")
|
|
async def me(user: CurrentUser, db: DbDep) -> dict:
|
|
perm_codes = await get_user_perm_codes(db, user)
|
|
menus = await get_user_menus(db, user)
|
|
tree = build_menu_tree(menus)
|
|
|
|
user_info = UserInfo(
|
|
id=user.id,
|
|
username=user.username,
|
|
nickname=user.nickname,
|
|
email=user.email,
|
|
avatar=user.avatar,
|
|
dept_id=user.dept_id,
|
|
dept_name=user.dept.name if user.dept else None,
|
|
is_superuser=user.is_superuser,
|
|
roles=[RoleBrief.model_validate(r) for r in user.roles],
|
|
perm_codes=perm_codes,
|
|
)
|
|
resp = MeResponse(user=user_info, menu_tree=tree)
|
|
return ok(resp.model_dump())
|