From f8d1c18927e56ab9227f32548aa3442f5e001e15 Mon Sep 17 00:00:00 2001 From: QihuAI Design Date: Fri, 17 Jul 2026 20:46:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E5=90=8E=E5=8F=B0=E6=9C=AA?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E8=AE=BF=E9=97=AE=20Skills/MCP/Agent=20?= =?UTF-8?q?=E6=8A=A5=20Not=20authenticated\n\n-=20AdminLayout=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=99=BB=E5=BD=95+=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E5=AE=88=E5=8D=AB=EF=BC=8C=E6=97=A0=20token=20=E6=88=96?= =?UTF-8?q?=E9=9D=9E=20admin=20=E8=B7=B3=20/login\n-=20api=20request()=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=20403=20Not=20authenticated/=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=AE=A1=E7=90=86=E5=91=98=E6=9D=83=E9=99=90=EF=BC=8C?= =?UTF-8?q?=E6=B8=85=20token=20=E8=B7=B3=E7=99=BB=E5=BD=95\n-=20=E6=A0=B9?= =?UTF-8?q?=E5=9B=A0=EF=BC=9AFastAPI=20HTTPBearer=20=E6=97=A0=20token=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=20403=20=E8=80=8C=E9=9D=9E=20401=EF=BC=8C?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=9C=AA=E5=A4=84=E7=90=86=20403=20=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/index.ts | 10 ++++++++++ frontend/src/components/layout/AdminLayout.tsx | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index f4ef003..6e67928 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -84,6 +84,16 @@ export async function request( } + if (res.status === 403) { + const err = await res.json().catch(() => ({ detail: 'Forbidden' })); + if (err.detail === 'Not authenticated' || err.detail === '需要管理员权限') { + localStorage.removeItem('aiflow_token'); + localStorage.removeItem('aiflow_user'); + window.location.href = '/login'; + throw new Error('未登录或权限不足'); + } + } + if (!res.ok) { const err = await res.json().catch(() => ({ detail: '请求失败' })); diff --git a/frontend/src/components/layout/AdminLayout.tsx b/frontend/src/components/layout/AdminLayout.tsx index 5cd3b65..fd74038 100644 --- a/frontend/src/components/layout/AdminLayout.tsx +++ b/frontend/src/components/layout/AdminLayout.tsx @@ -191,6 +191,15 @@ const AdminLayout: React.FC = () => { const location = useLocation(); + // 后台必须登录且为管理员 + useEffect(() => { + const token = localStorage.getItem('aiflow_token'); + if (!token || !user || user.role !== 'admin') { + logout(); + navigate('/login', { replace: true }); + } + }, [user, logout, navigate]); + const navCrumb = (() => { for (const g of adminNavGroups) {