一键导入
fec-route-protection
用于实现或审查前端路由保护、auth guard、RBAC、权限路由、登录态处理、重定向、middleware、React Router、Next.js、Vue Router 或 Nuxt route middleware;中文触发词包括 路由保护、权限路由、登录态。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
用于实现或审查前端路由保护、auth guard、RBAC、权限路由、登录态处理、重定向、middleware、React Router、Next.js、Vue Router 或 Nuxt route middleware;中文触发词包括 路由保护、权限路由、登录态。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
用于生成或编辑图表、图形资产、海报、UI 样机、产品图、信息图、学术图、漫画、头像、分镜、品牌板或图像编辑工作流,尤其是导出 PNG 需要视觉质检和有限自动修复时。文字密集图表优先使用确定性的 Mermaid/SVG/HTML/canvas 源;浏览器可打开的技术图优先使用 HTML technical diagrams,覆盖系统蓝图、架构图、部署拓扑、Agent runtime、memory flow、before-after architecture、流程、序列、数据流、生命周期、runbook、PII/数据血缘和状态机;不要用于不涉及生成图像的普通 UI 打磨。中文触发词包括 图片生成、图像编辑、图表生成、架构图、系统蓝图、部署拓扑、Agent runtime、memory flow、before-after architecture、工作流图、数据流、生命周期图、状态机、ER 图、UML、序列图、海报、UI 样机、产品图、信息图、学术图、漫画、头像、分镜、品牌板、PNG 自检、自动修复。
Use when generating or editing diagrams, charts, visual assets, posters, UI mockups, product images, infographics, academic figures, comics, avatars, storyboards, brand boards, or image-edit workflows, especially when exported PNGs need visual QA and bounded self-repair. Prefer deterministic Mermaid/SVG/HTML/canvas sources for text-heavy diagrams; use HTML technical diagrams for browser-ready system blueprints, architecture, deployment topology, agent runtime, memory flow, before-after architecture, workflow, sequence, data-flow, lifecycle, runbook, PII/data-lineage, and state-machine diagrams. Do not use for ordinary UI polish without generated imagery.
用于创建带 draw.io / diagrams.net 源文件的可编辑技术图,包括架构图、ERD、UML、序列图、流程图、ML 模型图、官方形状检索、品牌符号、Graphviz 自动布局、代码结构图、.drawio 校验或 draw.io CLI 导出兜底。不要用于普通位图生成、手绘草图、交互式 Canvas/Three.js 场景或装饰性 SVG 动画;中文触发词包括 draw.io、diagrams.net、可编辑架构图、.drawio、ER 图、UML、序列图、自动布局、形状检索、代码结构图。
Use when creating editable technical diagrams with draw.io / diagrams.net sources, including architecture diagrams, ERD, UML, sequence diagrams, flowcharts, ML model diagrams, official shape lookup, brand symbols, Graphviz auto-layout, codebase structure maps, .drawio validation, or draw.io CLI export fallback. Do not use for ordinary raster image generation, freehand sketches, interactive canvas/Three.js scenes, or decorative SVG animation. Chinese triggers include draw.io, diagrams.net, editable architecture diagrams, .drawio, ER diagrams, UML, sequence diagrams, auto layout, shape retrieval, code structure diagrams.
用于审查或改进前端无障碍、语义结构、键盘支持、焦点管理、ARIA 标签、屏幕阅读器行为、WCAG 2.2 问题、触控无障碍或辅助技术回归;中文触发词包括 无障碍、accessibility、a11y、WCAG、屏幕阅读器。
用于从参考系统中吸收想法、能力、工作流、架构、质量体系、生态扩展或工程实践,并通过原创的项目内重设计转化为当前项目能力,而不是复制原实现。
| name | fec-route-protection |
| description | 用于实现或审查前端路由保护、auth guard、RBAC、权限路由、登录态处理、重定向、middleware、React Router、Next.js、Vue Router 或 Nuxt route middleware;中文触发词包括 路由保护、权限路由、登录态。 |
为前端应用建立清晰的认证、授权和重定向边界,避免越权访问与闪烁渲染。
export type AuthStatus = "loading" | "anonymous" | "authenticated";
export interface CurrentUser {
id: string;
roles: string[];
permissions: string[];
}
export function canAccess(user: CurrentUser, required: string[]) {
return required.every((permission) => user.permissions.includes(permission));
}
import { Navigate, Outlet, useLocation } from "react-router-dom";
interface ProtectedRouteProps {
requiredPermissions?: string[];
}
export function ProtectedRoute({ requiredPermissions = [] }: ProtectedRouteProps) {
const location = useLocation();
const { status, user } = useAuth();
if (status === "loading") return <RouteLoading />;
if (status === "anonymous") {
return <Navigate to="/login" replace state={{ from: location }} />;
}
if (requiredPermissions.length > 0 && !canAccess(user, requiredPermissions)) {
return <Navigate to="/403" replace />;
}
return <Outlet />;
}
const router = createBrowserRouter([
{
element: <ProtectedRoute requiredPermissions={["orders:read"]} />,
children: [{ path: "/orders", element: <OrdersPage /> }],
},
]);
// middleware.ts
import { NextResponse, type NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("session")?.value;
const isPrivateRoute = request.nextUrl.pathname.startsWith("/dashboard");
if (isPrivateRoute && !token) {
const loginUrl = new URL("/login", request.url);
loginUrl.searchParams.set("redirect", request.nextUrl.pathname);
return NextResponse.redirect(loginUrl);
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*"],
};
对需要精细权限的 App Router 页面,在 server component 或 server action 中重新校验权限,不依赖客户端状态。
router.beforeEach(async (to) => {
const auth = useAuthStore();
if (auth.status === "unknown") await auth.fetchCurrentUser();
if (to.meta.requiresAuth && !auth.user) {
return { path: "/login", query: { redirect: to.fullPath } };
}
const required = to.meta.permissions as string[] | undefined;
if (required?.length && !auth.canAccess(required)) {
return { path: "/403" };
}
});
401:清理过期会话,跳转登录页并保留 redirect。403:进入无权限页,不反复重试。loading:渲染稳定骨架屏,避免先显示私有内容再跳转。useEffect 才跳转私有页面,否则会出现敏感内容闪烁。产出一套路由守卫实现,覆盖 loading、未登录、权限不足、登录后回跳和会话过期。验证时直接访问私有 URL、刷新页面、切换角色、篡改 redirect 参数,确认行为稳定且 API 仍有服务端授权。