安全

路由保护

基于 URL 模式的认证、权限和订阅访问控制

路由保护

路由保护模块(packages/auth/src/route-protection.ts)提供了一套与具体框架无关的路由访问控制工具。它通过正则表达式匹配 URL,然后根据配置决定是否放行。

工作原理

每个路由配置包含以下字段:

interface RouteConfig {
  pattern: RegExp;              // URL 匹配模式
  type: "page" | "api";        // 路由类型(影响响应格式)
  requiresAuth?: boolean;       // 是否需要登录(默认 true)
  requiredPermission?: {        // 所需权限
    action: string;
    subject: string;
  };
  requiresSubscription?: boolean; // 是否需要有效订阅
  isAuthRoute?: boolean;        // 是否为登录页(登录用户会被重定向走)
}

检查结果有四种拒绝理由:unauthenticated(未登录)、forbidden(无权限)、subscription_required(需要订阅)、redirect_authenticated(已登录用户不应访问登录页)。

使用示例

import { matchRoute, checkRouteAccess } from "@01mvp/auth/route-protection";

// 定义路由规则
const routes = [
  { pattern: /^\/admin/, type: "page", requiredPermission: { action: "manage", subject: "all" } },
  { pattern: /^\/dashboard/, type: "page", requiresAuth: true },
  { pattern: /^\/login/, type: "page", isAuthRoute: true },
  { pattern: /^\/api\/premium/, type: "api", requiresSubscription: true },
];

// 在中间件中使用
const route = matchRoute(pathname, routes);
if (route) {
  const result = checkRouteAccess(route, {
    isAuthenticated: !!session,
    userId: session?.user?.id,
    hasSubscription: userHasSub,
    checkPermission: (action, subject) => can(user, action, subject),
  });
  if (!result.allowed) {
    if (result.redirectUrl) return redirect(result.redirectUrl);
    return new Response(result.reason, { status: result.statusCode });
  }
}