Token导航 LogoToken导航

Agent Skill · 研究检索

middleware-protection(中间件保护)

middleware-protection 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

middleware-protection 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 47,825。

总安装 717周安装 29GitHub Stars 777下载 225核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:middleware-protection(中间件保护)
来源仓库:https://github.com/dadbodgeoff/drift
仓库路径:skills/middleware-protection
安装命令:
npx skills add https://github.com/dadbodgeoff/drift --skill middleware-protection
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/dadbodgeoff/drift --skill middleware-protection

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于中间件安全防护方案的检索与筛选。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。适合查找鉴权、限流或防注入等保护机制。通过 GitHub 安装,建议核实维护状态与使用限制。使用时需注意是否涉及敏感操作或外部调用。

middleware-protection 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/middleware-protection

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/dadbodgeoff/drift --skill middleware-protectio…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

middleware-protection 怎么安装?

在终端执行 npx skills add https://github.com/dadbodgeoff/drift --skill middleware-protection。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

middleware-protection 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

middleware-protection 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

middleware-protection 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

middleware-protection 用的人多吗?

公开数据是累计安装 717 次,近一周安装 29 次,下载 225 次,GitHub 777 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

middleware-protection 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
middleware-protection

中间件保护 · 本页

717777需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Middleware Route Protection

Check auth once, protect routes declaratively.

When to Use This Skill

  • Need to protect multiple routes
  • Want centralized auth checking
  • Tired of repeating auth logic in every route
  • Need role-based access control

Core Concepts

  1. Middleware intercepts - All requests pass through middleware
  2. Declarative routes - Define protected/public routes in config
  3. Session refresh - Keep sessions alive automatically
  4. Consistent errors - API routes get JSON, pages get redirects

TypeScript Implementation

middleware.ts

// middleware.ts
import { createServerClient } from '@supabase/ssr';
import { NextResponse, type NextRequest } from 'next/server';

// Routes that require authentication
const PROTECTED_ROUTES = [
  '/dashboard',
  '/settings',
  '/api/user',
  '/api/predictions',
];

// Routes that are always public
const PUBLIC_ROUTES = [
  '/',
  '/login',
  '/signup',
  '/api/health',
  '/api/public',
];

export async function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  // Skip static files and Next.js internals
  if (
    pathname.startsWith('/_next') ||
    pathname.startsWith('/favicon') ||
    pathname.match(/\.(svg|png|jpg|jpeg|gif|webp|ico)$/)
  ) {
    return NextResponse.next();
  }

  // Skip explicitly public routes
  if (PUBLIC_ROUTES.some(route => pathname === route || pathname.startsWith(route + '/'))) {
    return NextResponse.next();
  }

  // Create response that we'll modify
  let response = NextResponse.next({ request });

  // Create Supabase client with cookie handling
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value }) =>
            request.cookies.set(name, value)
          );
          response = NextResponse.next({ request });
          cookiesToSet.forEach(({ name, value, options }) =>
            response.cookies.set(name, value, options)
          );
        },
      },
    }
  );

  // Refresh session (important for SSR)
  const { data: { user } } = await supabase.auth.getUser();

  // Check if route requires auth
  const requiresAuth = PROTECTED_ROUTES.some(route =>
    pathname === route || pathname.startsWith(route + '/')
  );

  if (requiresAuth && !user) {
    // API routes: return 401 JSON
    if (pathname.startsWith('/api/')) {
      return NextResponse.json(
        {
          error: 'Authentication required',
          code: 'AUTH_REQUIRED',
          loginUrl: '/login',
        },
        { status: 401 }
      );
    }

    // Pages: redirect to login with return URL
    const url = request.nextUrl.clone();
    url.pathname = '/login';
    url.searchParams.set('redirectTo', pathname);
    return NextResponse.redirect(url);
  }

  // Add user ID to headers for downstream use
  if (user) {
    response.headers.set('x-user-id', user.id);
  }

  return response;
}

export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
  ],
};

Using User ID in API Routes

// app/api/user/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { createServerSupabaseClient } from '@/lib/supabase-server';

export async function GET(request: NextRequest) {
  // User ID was added by middleware
  const userId = request.headers.get('x-user-id');

  if (!userId) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  const supabase = await createServerSupabaseClient();

  const { data: profile } = await supabase
    .from('user_profiles')
    .select('*')
    .eq('id', userId)
    .single();

  return NextResponse.json({ profile });
}

Role-Based Protection

// middleware.ts (extended)

const ROUTE_ROLES: Record<string, string[]> = {
  '/admin': ['admin'],
  '/dashboard': ['user', 'admin'],
  '/api/admin': ['admin'],
};

// After getting user, check role
if (user) {
  const userRole = user.user_metadata?.role || 'user';

  const requiredRoles = Object.entries(ROUTE_ROLES)
    .find(([route]) => pathname.startsWith(route))?.[1];

  if (requiredRoles && !requiredRoles.includes(userRole)) {
    if (pathname.startsWith('/api/')) {
      return NextResponse.json(
        { error: 'Forbidden', code: 'FORBIDDEN' },
        { status: 403 }
      );
    }
    return NextResponse.redirect(new URL('/unauthorized', request.url));
  }
}

Pattern-Based Routes

// For more complex route matching
const PROTECTED_PATTERNS = [
  /^\/dashboard(\/.*)?$/,
  /^\/api\/user\/.*$/,
  /^\/settings$/,
  /^\/api\/v\d+\/private\/.*/,  // /api/v1/private/*, /api/v2/private/*
];

const requiresAuth = PROTECTED_PATTERNS.some(pattern =>
  pattern.test(pathname)
);

Python Implementation (FastAPI)

# middleware/auth.py
from fastapi import Request, HTTPException
from fastapi.responses import RedirectResponse
from starlette.middleware.base import BaseHTTPMiddleware
from typing import Set

PROTECTED_ROUTES: Set[str] = {
    "/dashboard",
    "/settings",
    "/api/user",
}

PUBLIC_ROUTES: Set[str] = {
    "/",
    "/login",
    "/signup",
    "/api/health",
}

class AuthMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        path = request.url.path

        # Skip public routes
        if path in PUBLIC_ROUTES or any(path.startswith(r + "/") for r in PUBLIC_ROUTES):
            return await call_next(request)

        # Check if route requires auth
        requires_auth = path in PROTECTED_ROUTES or any(
            path.startswith(r + "/") for r in PROTECTED_ROUTES
        )

        if not requires_auth:
            return await call_next(request)

        # Get user from session/token
        user = await get_user_from_request(request)

        if not user:
            if path.startswith("/api/"):
                raise HTTPException(
                    status_code=401,
                    detail={
                        "error": "Authentication required",
                        "code": "AUTH_REQUIRED",
                        "login_url": "/login",
                    }
                )
            return RedirectResponse(f"/login?redirectTo={path}")

        # Add user to request state
        request.state.user = user
        request.state.user_id = user.id

        return await call_next(request)

async def get_user_from_request(request: Request):
    """Extract and validate user from request."""
    token = request.cookies.get("session") or request.headers.get("Authorization")
    if not token:
        return None
    # Validate token and return user
    return await validate_session(token)
# Using in routes
from fastapi import Request, Depends

@app.get("/api/user/profile")
async def get_profile(request: Request):
    user_id = request.state.user_id
    profile = await db.get_profile(user_id)
    return {"profile": profile}

Error Response Format

// Consistent error format for API routes
interface AuthError {
  error: string;
  code: 'AUTH_REQUIRED' | 'SESSION_EXPIRED' | 'FORBIDDEN';
  message?: string;
  loginUrl: string;
}

// 401 - Not authenticated
{
  "error": "Authentication required",
  "code": "AUTH_REQUIRED",
  "loginUrl": "/login"
}

// 403 - Authenticated but not authorized
{
  "error": "Forbidden",
  "code": "FORBIDDEN",
  "message": "Admin access required"
}

Best Practices

  1. Refresh sessions - Call getUser() in middleware to refresh
  2. Pass user ID - Add to headers for downstream routes
  3. JSON for APIs - Never redirect API routes
  4. Return URL - Include redirectTo param for login redirects
  5. Skip static - Don't process static files

Common Mistakes

  • Redirecting API routes (should return 401 JSON)
  • Not refreshing session in middleware
  • Processing static files through auth
  • Missing return URL on login redirect
  • Not handling role-based access

Related Skills

平台分布

Codex

38.68%
按下载量换算87

Claude

28.94%
按下载量换算65

Cursor

17.91%
按下载量换算40

Gemini CLI

8.73%
按下载量换算20

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills