clerk-validator

安装量: 64
排名: #11720

安装

npx skills add https://github.com/shipshitdev/library --skill clerk-validator

Clerk Validator

Validates Clerk authentication configuration and prevents deprecated patterns. AI assistants often generate old Clerk patterns - this skill enforces modern Clerk with Next.js 16.

When This Activates Setting up Clerk authentication Before any auth implementation work Auditing existing Clerk configuration After AI generates Clerk code CI/CD pipeline validation Quick Start python3 ~/.claude/skills/clerk-validator/scripts/validate.py --root . python3 ~/.claude/skills/clerk-validator/scripts/validate.py --root . --strict

What Gets Checked 1. Package Version // GOOD: Latest Clerk "@clerk/nextjs": "^6.0.0"

// BAD: Old version "@clerk/nextjs": "^4.0.0"

  1. Proxy vs Middleware (Next.js 16)

GOOD - Next.js 16:

// proxy.ts import { clerkMiddleware } from "@clerk/nextjs/server"; export default clerkMiddleware();

BAD - Deprecated:

// middleware.ts (deprecated in Next.js 16) import { authMiddleware } from "@clerk/nextjs"; // DEPRECATED export default authMiddleware();

  1. ClerkProvider Setup

GOOD:

// app/layout.tsx import { ClerkProvider } from "@clerk/nextjs";

export default function RootLayout({ children }) { return ( <html> <body>{children}</body> </html> ); }

BAD - Missing or wrong location:

// Don't put in _app.tsx (Pages Router deprecated) // Don't forget to wrap the entire app

  1. Auth Import Patterns

GOOD - Server-side:

import { auth } from "@clerk/nextjs/server";

export default async function Page() { const { userId } = await auth(); // ... }

BAD - Old patterns:

// Don't use import { getAuth } from "@clerk/nextjs/server"; // OLD import { currentUser } from "@clerk/nextjs"; // Check version

  1. Environment Variables

Required:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_... CLERK_SECRET_KEY=sk_...

Optional but recommended:

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding

Deprecated Patterns Deprecated Replacement authMiddleware() clerkMiddleware() middleware.ts proxy.ts (Next.js 16) getAuth() auth() @clerk/nextjs < v5 @clerk/nextjs@latest _app.tsx provider app/layout.tsx provider withClerkMiddleware clerkMiddleware() Validation Output === Clerk Validation Report ===

Package Version: @clerk/nextjs@6.0.0 ✓

Configuration: ✓ ClerkProvider in app/layout.tsx ✓ proxy.ts with clerkMiddleware ✗ Found middleware.ts - should use proxy.ts for Next.js 16 ✓ Environment variables configured

Auth Patterns: ✓ Using auth() from @clerk/nextjs/server ✗ Found deprecated authMiddleware() in 1 file

Summary: 2 issues found

Modern Clerk Patterns Protected Routes (Server Component) // app/dashboard/page.tsx import { auth } from "@clerk/nextjs/server"; import { redirect } from "next/navigation";

export default async function DashboardPage() { const { userId } = await auth();

if (!userId) { redirect("/sign-in"); }

return ; }

Protected Routes (Client Component) "use client"; import { useAuth } from "@clerk/nextjs";

export default function ProtectedComponent() { const { isLoaded, userId } = useAuth();

if (!isLoaded) return ; if (!userId) return ;

return ; }

API Routes // app/api/protected/route.ts import { auth } from "@clerk/nextjs/server"; import { NextResponse } from "next/server";

export async function GET() { const { userId } = await auth();

if (!userId) { return new NextResponse("Unauthorized", { status: 401 }); }

return NextResponse.json({ userId }); }

NestJS Guard // auth/clerk.guard.ts import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common"; import { clerkClient } from "@clerk/clerk-sdk-node";

@Injectable() export class ClerkGuard implements CanActivate { async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const token = this.extractToken(request);

if (!token) return false;

try {
  const { userId } = await clerkClient.verifyToken(token);
  request.userId = userId;
  return true;
} catch {
  return false;
}

}

private extractToken(request: any): string | null { const auth = request.headers.authorization; if (!auth?.startsWith("Bearer ")) return null; return auth.slice(7); } }

Webhook Configuration // app/api/webhooks/clerk/route.ts import { Webhook } from "svix"; import { headers } from "next/headers"; import { WebhookEvent } from "@clerk/nextjs/server";

export async function POST(req: Request) { const WEBHOOK_SECRET = process.env.CLERK_WEBHOOK_SECRET; if (!WEBHOOK_SECRET) throw new Error("Missing CLERK_WEBHOOK_SECRET");

const headerPayload = headers(); const svix_id = headerPayload.get("svix-id"); const svix_timestamp = headerPayload.get("svix-timestamp"); const svix_signature = headerPayload.get("svix-signature");

const body = await req.text(); const wh = new Webhook(WEBHOOK_SECRET); const evt = wh.verify(body, { "svix-id": svix_id!, "svix-timestamp": svix_timestamp!, "svix-signature": svix_signature!, }) as WebhookEvent;

// Handle event switch (evt.type) { case "user.created": // Sync to database break; }

return new Response("OK", { status: 200 }); }

CI/CD Integration

.github/workflows/validate.yml

  • name: Validate Clerk Config run: | python3 ~/.claude/skills/clerk-validator/scripts/validate.py \ --root . \ --strict \ --ci

Integration nextjs-validator - Validates Next.js 16 (proxy.ts) biome-validator - Validates linting config git-safety - Ensures no secrets committed

返回排行榜