Token导航 LogoToken导航

Agent Skill · 研究检索

router-core%2fauth-and-guards(路由器核心%2fauth 和守卫)

用于辅助安全审计、权限检查、凭据风险、认证流程和常见漏洞排查。它适合让 Agent 梳理敏感配置、检查依赖风险、分析鉴权逻辑或生成安全复核清单。使用时不能把工具输出直接当最终结论,涉及密钥、令牌、用户数据或生产系统时,应先确认最小权限、脱敏方式和操作边界。

router-core%2fauth-and-guards 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证信息还不明确,暂无第三方扫描结果,按安装量在研究检索类的 73,675 个 Skill 里排第 42,544。

总安装 1,063周安装 43GitHub Stars 14,323下载 334核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:router-core%2fauth-and-guards(路由器核心%2fauth 和守卫)
来源仓库:https://github.com/tanstack/router
仓库路径:skills/router-core%2Fauth-and-guards
安装命令:
npx skills add https://github.com/tanstack/router --skill router-core/auth-and-guards
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/tanstack/router --skill router-core/auth-and-guards

这个 Skill 是做什么的

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

router-core/auth-and-guards 用于辅助安全审计、权限检查和认证流程分析,适合在 Codex、Claude、Cursor、Gemini CLI 中梳理敏感配置或生成安全复核清单时使用。它适用于安全相关场景,如检查依赖风险、分析鉴权逻辑或排查常见漏洞。

通过 npx skills add 命令从指定 GitHub 仓库安装并使用该技能。使用时不能将工具输出直接当作最终结论,涉及密钥或用户数据时应先确认最小权限和操作边界。router-core%2fauth-and-guards 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/router-core%2Fauth-and-guards

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

router-core%2fauth-and-guards 怎么安装?

在终端执行 npx skills add https://github.com/tanstack/router --skill router-core/auth-and-guards。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

router-core%2fauth-and-guards 支持哪些 AI 工具?

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

router-core%2fauth-and-guards 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

router-core%2fauth-and-guards 是免费的吗?

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

router-core%2fauth-and-guards 用的人多吗?

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

router-core%2fauth-and-guards 安全吗?

没有查到第三方扫描结果,安全性无法从公开资料判断,安装前请自行审查源码、依赖和命令行为。

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 来源仓库有 14,323 星,维护活跃度相对可查。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 没有第三方扫描结果,安全性只能靠自己读源码判断。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 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调用外部服务未明确有提醒
router-core%2fauth-and-guards

路由器核心%2fauth 和守卫 · 本页

1,06314,323权限未标注未明确未收录

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

SKILL.md 原文

Auth and Guards

Setup

Protect routes with beforeLoad + redirect() in a pathless layout route (_authenticated):

// src/routes/_authenticated.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: {
          redirect: location.href,
        },
      })
    }
  },
  // component defaults to Outlet — no need to declare it
})

Any route file placed under src/routes/_authenticated/ is automatically protected:

// src/routes/_authenticated/dashboard.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/dashboard')({
  component: DashboardComponent,
})

function DashboardComponent() {
  const { auth } = Route.useRouteContext()
  return <div>Welcome, {auth.user?.username}</div>
}

Core Patterns

Router Context for Auth State

Auth state flows into the router via createRootRouteWithContext and RouterProvider's context prop:

// src/routes/__root.tsx
import { createRootRouteWithContext, Outlet } from '@tanstack/react-router'

interface AuthState {
  isAuthenticated: boolean
  user: { id: string; username: string; email: string } | null
  login: (username: string, password: string) => Promise<void>
  logout: () => void
}

interface MyRouterContext {
  auth: AuthState
}

export const Route = createRootRouteWithContext<MyRouterContext>()({
  component: () => <Outlet />,
})
// src/router.tsx
import { createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

export const router = createRouter({
  routeTree,
  context: {
    auth: undefined!, // placeholder — filled by RouterProvider context prop
  },
})

declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }
}
// src/App.tsx
import { RouterProvider } from '@tanstack/react-router'
import { AuthProvider, useAuth } from './auth'
import { router } from './router'

function InnerApp() {
  const auth = useAuth()
  // context prop injects live auth state WITHOUT recreating the router
  return <RouterProvider router={router} context={{ auth }} />
}

function App() {
  return (
    <AuthProvider>
      <InnerApp />
    </AuthProvider>
  )
}

The router is created once with a placeholder. RouterProvider's context prop injects the live auth state on each render — this avoids recreating the router on auth changes (which would reset caches and rebuild the route tree).

Redirect-Based Auth with Redirect-Back

Save the current location in search params so you can redirect back after login:

// src/routes/_authenticated.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({
        to: '/login',
        search: { redirect: location.href },
      })
    }
  },
})
// src/routes/login.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'
import { useState, type FormEvent } from 'react'

// Validate redirect target to prevent open redirect attacks
function sanitizeRedirect(url: unknown): string {
  if (typeof url !== 'string' || !url.startsWith('/') || url.startsWith('//')) {
    return '/'
  }
  return url
}

export const Route = createFileRoute('/login')({
  validateSearch: (search) => ({
    redirect: sanitizeRedirect(search.redirect),
  }),
  beforeLoad: ({ context, search }) => {
    if (context.auth.isAuthenticated) {
      throw redirect({ to: search.redirect })
    }
  },
  component: LoginComponent,
})

function LoginComponent() {
  const { auth } = Route.useRouteContext()
  const search = Route.useSearch()
  const navigate = Route.useNavigate()
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [error, setError] = useState('')

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault()
    try {
      await auth.login(username, password)
      navigate({ to: search.redirect })
    } catch {
      setError('Invalid credentials')
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <div>{error}</div>}
      <input value={username} onChange={(e) => setUsername(e.target.value)} />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
      <button type="submit">Sign In</button>
    </form>
  )
}

Non-Redirect Auth (Inline Login)

Instead of redirecting, show a login form in place of the Outlet:

// src/routes/_authenticated.tsx
import { createFileRoute, Outlet } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated')({
  component: AuthenticatedLayout,
})

function AuthenticatedLayout() {
  const { auth } = Route.useRouteContext()

  if (!auth.isAuthenticated) {
    return <LoginForm />
  }

  return <Outlet />
}

This keeps the URL unchanged — the user stays on the same page and sees a login form instead of protected content. After authentication, <Outlet /> renders and child routes appear.

RBAC with Roles and Permissions

Extend auth state with role/permission helpers, then check in beforeLoad:

// src/auth.tsx
interface User {
  id: string
  username: string
  email: string
  roles: string[]
  permissions: string[]
}

interface AuthState {
  isAuthenticated: boolean
  user: User | null
  hasRole: (role: string) => boolean
  hasAnyRole: (roles: string[]) => boolean
  hasPermission: (permission: string) => boolean
  hasAnyPermission: (permissions: string[]) => boolean
  login: (username: string, password: string) => Promise<void>
  logout: () => void
}

Admin-only layout route:

// src/routes/_authenticated/_admin.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/_admin')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.hasRole('admin')) {
      throw redirect({
        to: '/unauthorized',
        search: { redirect: location.href },
      })
    }
  },
})

Multi-role access:

// src/routes/_authenticated/_moderator.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/_moderator')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.hasAnyRole(['admin', 'moderator'])) {
      throw redirect({
        to: '/unauthorized',
        search: { redirect: location.href },
      })
    }
  },
})

Permission-based:

// src/routes/_authenticated/_users.tsx
import { createFileRoute, redirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/_users')({
  beforeLoad: ({ context, location }) => {
    if (!context.auth.hasAnyPermission(['users:read', 'users:write'])) {
      throw redirect({
        to: '/unauthorized',
        search: { redirect: location.href },
      })
    }
  },
})

Page-level permission check (nested under an already-role-protected layout):

// src/routes/_authenticated/_users/manage.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated/_users/manage')({
  beforeLoad: ({ context }) => {
    if (!context.auth.hasPermission('users:write')) {
      throw new Error('Write permission required')
    }
  },
  component: UserManagement,
})

function UserManagement() {
  const { auth } = Route.useRouteContext()
  const canDelete = auth.hasPermission('users:delete')

  return (
    <div>
      <h1>User Management</h1>
      {canDelete && <button>Delete User</button>}
    </div>
  )
}

Handling Auth Check Failures (isRedirect)

When beforeLoad has a try/catch, redirects (which work by throwing) can get swallowed. Use isRedirect to re-throw:

import { createFileRoute, redirect, isRedirect } from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated')({
  beforeLoad: async ({ context, location }) => {
    try {
      const user = await verifySession(context.auth)
      if (!user) {
        throw redirect({
          to: '/login',
          search: { redirect: location.href },
        })
      }
      return { user }
    } catch (error) {
      if (isRedirect(error)) throw error // re-throw redirect, don't swallow it
      // Actual error — redirect to login
      throw redirect({
        to: '/login',
        search: { redirect: location.href },
      })
    }
  },
})

Common Mistakes

HIGH: Auth check in component instead of beforeLoad

Component-level auth checks cause a flash of protected content before the redirect:

// WRONG — protected content renders briefly before redirect
export const Route = createFileRoute('/_authenticated/dashboard')({
  component: () => {
    const auth = useAuth()
    if (!auth.isAuthenticated) return <Navigate to="/login" />
    return <Dashboard />
  },
})

// CORRECT — beforeLoad runs before any rendering
export const Route = createFileRoute('/_authenticated/dashboard')({
  beforeLoad: ({ context }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({ to: '/login' })
    }
  },
  component: Dashboard,
})

beforeLoad runs before any component rendering and before the loader. It completely prevents the flash.

HIGH: Not re-throwing redirects in try/catch

redirect() works by throwing. If beforeLoad has a try/catch, the redirect gets swallowed:

// WRONG — redirect is caught and swallowed
beforeLoad: async ({ context }) => {
  try {
    await validateSession(context.auth)
  } catch (e) {
    console.error(e) // swallows the redirect!
  }
}

// CORRECT — use isRedirect to distinguish intentional redirects from errors
import { isRedirect } from '@tanstack/react-router'

beforeLoad: async ({ context }) => {
  try {
    await validateSession(context.auth)
  } catch (e) {
    if (isRedirect(e)) throw e
    console.error(e)
  }
}

MEDIUM: Conditionally rendering root route component

The root route always renders regardless of auth state. You cannot conditionally render its component:

// WRONG — root route always renders, this doesn't protect anything
export const Route = createRootRoute({
  component: () => {
    if (!isAuthenticated()) return <Login />
    return <Outlet />
  },
})

// CORRECT — use a pathless layout route for auth boundaries
// src/routes/_authenticated.tsx
export const Route = createFileRoute('/_authenticated')({
  beforeLoad: ({ context }) => {
    if (!context.auth.isAuthenticated) {
      throw redirect({ to: '/login' })
    }
  },
})

Place protected routes as children of the _authenticated layout route. Public routes (login, home, etc.) live outside it.


Cross-References

  • See also: router-core/data-loading/SKILL.md — beforeLoad runs before loader; auth context flows into loader via route context

平台分布

Codex

37.23%
按下载量换算124

Claude

29.14%
按下载量换算97

Cursor

16.5%
按下载量换算55

Gemini CLI

8.86%
按下载量换算30

安全审计

暂无安全审计结果可展示。

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

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

继续浏览同类 Skills