本文へ移動
cccskills
無料GitHub で公開

clerk-auth

Clerk is a hosted authentication and user-management service with drop-in UI components, social login, email/password, organizations, RBAC and webhooks. Use when adding sign-in to Next.js, React, or Express apps, protecting routes with clerkMiddleware, setting up multi-tenant organizations and roles, or syncing Clerk users to your own database.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md13.0 KB
  • _scores.json2.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Clerk Authentication

Overview

Clerk provides hosted sign-in and sign-up, session management, user profiles, organizations (multi-tenancy) and role-based access control. Your app wraps itself in a provider, adds a middleware that attaches the session, checks it next to the data, and reads the session through auth() on the server or hooks on the client. Keys come from the Clerk dashboard (Configure, API keys). Use the pk_test_/sk_test_ keys for development and the pk_live_/sk_live_ pair only in production. Checked against @clerk/nextjs 7.9 and @clerk/express 2.1 (Clerk Core 3). Core 3 replaced <SignedIn>, <SignedOut> and <Protect> with <Show>, requires ClerkProvider inside <body>, and dropped Next.js 13 and 14.

Instructions

1. Install and configure (Next.js App Router)

Clerk's own quickstart now starts from its CLI, which detects the framework, installs the SDK, writes dev keys to .env.local and creates the middleware file (no account needed to start; it provisions a claimable dev app): npx -y clerk@latest init, then npx -y clerk@latest doctor to check the setup. Manual setup:

npm install @clerk/nextjs
# .env.local
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=   # publishable key from the Clerk dashboard (API keys)
CLERK_SECRET_KEY=                    # secret key from the same page; never commit it
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
// app/layout.tsx
import { ClerkProvider, Show, SignInButton, SignUpButton, UserButton } from '@clerk/nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ClerkProvider afterSignOutUrl="/">
          <header>
            <Show when="signed-out"><SignInButton /><SignUpButton /></Show>
            <Show when="signed-in"><UserButton /></Show>
          </header>
          {children}
        </ClerkProvider>
      </body>
    </html>
  );
}

2. Add clerkMiddleware, then protect at the resource

On Next.js 16 the file is proxy.ts; on Next.js 15 it is middleware.ts. The code is identical. clerkMiddleware() only attaches the session to the request and protects nothing by default.

// proxy.ts (middleware.ts on Next.js 15)
import { clerkMiddleware } from '@clerk/nextjs/server';

export default clerkMiddleware();

export const config = {
  matcher: [
    '/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
    '/(api|trpc)(.*)',
    '/__clerk/(.*)',
  ],
};

Clerk's docs now say middleware is not the best place to protect routes: put the check in the code that reads or changes the data (pages, layouts that prefetch data, route handlers, server actions). createRouteMatcher() with auth.protect() inside clerkMiddleware still works but is deprecated, so write new code with per-resource checks.

// app/dashboard/page.tsx
import { auth } from '@clerk/nextjs/server';

export default async function Dashboard() {
  await auth.protect(); // signed out: redirect to sign-in
  return <h1>Dashboard</h1>;
}

auth.protect() on a page redirects signed-out users to sign-in. In a route handler it returns 404 for an unauthenticated request (401 inside a server action), and a signed-in user lacking the required role or permission gets 404. If you want control over the response, call auth() and check isAuthenticated yourself (next step).

3. Read the session on the server

import { auth, currentUser } from '@clerk/nextjs/server';

export default async function Page() {
  const { isAuthenticated, userId, orgId, orgRole, redirectToSignIn } = await auth();
  if (!isAuthenticated) return redirectToSignIn();

  const user = await currentUser(); // full user object (counts as a Backend API request)
  return <p>Hello {user?.firstName}</p>;
}

auth() is async in current versions: always await it. In a route handler return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) when userId is null.

4. Client hooks and components

'use client';
import { useAuth, useUser, useOrganization } from '@clerk/nextjs';

export function ProfileCard() {
  const { isSignedIn } = useAuth();
  const { user } = useUser();
  const { organization, membership } = useOrganization();
  if (!isSignedIn) return <p>Not signed in</p>;
  return <p>{user?.fullName} / {organization?.name} / {membership?.role}</p>;
}

Pre-built components from @clerk/nextjs: SignIn, SignUp, UserButton, UserProfile, OrganizationSwitcher, OrganizationList, OrganizationProfile. Mount the sign-in page at a catch-all route:

// app/sign-in/[[...sign-in]]/page.tsx
import { SignIn } from '@clerk/nextjs';
export default function SignInPage() { return <SignIn />; }

Show or hide UI with <Show when="signed-in">, <Show when="signed-out"> or <Show when={{ permission: 'org:invoices:create' }} fallback={...}>; it replaces SignedIn, SignedOut and Protect. It only hides content visually, so never rely on it for security. The sign-out redirect is not a UserButton prop any more; pass afterSignOutUrl="/" to <ClerkProvider>. The old afterSignInUrl/afterSignUpUrl props became fallbackRedirectUrl and signUpFallbackRedirectUrl.

5. Organizations and roles

Enable Organizations in the dashboard first. The default roles are org:admin and org:member; extra roles and permissions (for example org:projects:manage) are defined under Organizations, Roles and permissions. There is no built-in org:owner role, so do not assume one exists.

import { auth, clerkClient } from '@clerk/nextjs/server';

export async function createOrg(name: string) {
  const { userId } = await auth();
  const client = await clerkClient(); // async in current versions
  return client.organizations.createOrganization({ name, createdBy: userId! });
}

export async function inviteMember(organizationId: string, emailAddress: string) {
  const { userId } = await auth();
  const client = await clerkClient();
  return client.organizations.createOrganizationInvitation({
    organizationId,
    emailAddress,
    role: 'org:member',
    inviterUserId: userId!,
  });
}

Authorization checks with has():

const { has } = await auth();
if (!has({ role: 'org:admin' })) throw new Error('Forbidden');
if (!has({ permission: 'org:projects:manage' })) throw new Error('Forbidden');

Prefer permission checks: they survive role renames. On the server has({ permission }) only evaluates custom permissions you defined in the dashboard (check the role for system permissions), and role or permission checks need an active organization; without one they return false.

6. Webhooks

Create an endpoint in the dashboard (Configure, Webhooks), subscribe to events, and copy the signing secret into CLERK_WEBHOOK_SIGNING_SECRET. The route must be reachable without a session (do not call auth.protect() there). verifyWebhook (from @clerk/nextjs/webhooks) reads that variable and validates the signature, so you no longer need to wire up svix yourself.

// app/api/webhooks/clerk/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks';
import type { NextRequest } from 'next/server';

export async function POST(req: NextRequest) {
  try {
    const evt = await verifyWebhook(req);
    switch (evt.type) {
      case 'user.created':
        await db.users.create({ data: {
          clerkId: evt.data.id,
          email: evt.data.email_addresses[0]?.email_address,
          name: `${evt.data.first_name ?? ''} ${evt.data.last_name ?? ''}`.trim(),
        }});
        break;
      case 'user.deleted':
        await db.users.deleteMany({ where: { clerkId: evt.data.id } });
        break;
      case 'organization.created':
        await db.orgs.create({ data: { clerkOrgId: evt.data.id, name: evt.data.name, slug: evt.data.slug } });
        break;
    }
    return new Response('OK', { status: 200 });
  } catch {
    return new Response('Invalid webhook', { status: 400 });
  }
}

Common events: user.created, user.updated, user.deleted, organization.created, organization.updated, organizationMembership.created, organizationMembership.deleted. Any non-2xx response makes Clerk retry; locally, expose the route with a tunnel.

7. JWT templates for external APIs

Create a template in the dashboard (Configure, JWT templates), for example api-token with claims { "userId": "{{user.id}}", "orgId": "{{org.id}}", "role": "{{org.role}}" }.

// client
const { getToken } = useAuth();
const token = await getToken({ template: 'api-token' });

// external service
import { verifyToken } from '@clerk/backend';

export async function verifyRequest(req: Request) {
  const token = req.headers.get('Authorization')?.replace('Bearer ', '');
  if (!token) throw new Error('Missing token');
  return verifyToken(token, { secretKey: process.env.CLERK_SECRET_KEY });
}

A JWT template token is not bound to a session (no sid). If you only need extra claims on the normal session token, use a customised session token instead.

8. Express

The old @clerk/clerk-sdk-node package has been superseded by @clerk/express, and requireAuth() is deprecated in favour of clerkMiddleware() plus getAuth().

npm install @clerk/express
import express from 'express';
import { clerkMiddleware, getAuth } from '@clerk/express';

const app = express();
app.use(clerkMiddleware());

app.get('/api/me', (req, res) => {
  const { isAuthenticated, userId, orgId } = getAuth(req);
  if (!isAuthenticated) return res.status(401).json({ error: 'Unauthorized' });
  res.json({ userId, orgId });
});

@clerk/express reads CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY from the environment (no NEXT_PUBLIC_ prefix outside Next.js).

Examples

Example 1: "Make everything under /dashboard private in my Next.js 15 app"

Run npx -y clerk@latest init (or add the two keys to .env.local and wrap app/layout.tsx in <ClerkProvider> inside <body>), keep the proxy.ts/middleware.ts from step 2, and protect the layout that fetches dashboard data:

// app/dashboard/layout.tsx
import { auth } from '@clerk/nextjs/server';

export default async function DashboardLayout({ children }: { children: React.ReactNode }) {
  await auth.protect();
  return <section>{children}</section>;
}

Check again in each route handler and server action under /dashboard: a layout alone does not re-run on client-side navigation.

Result: visiting /dashboard signed out redirects to /sign-in; after signing in the user lands back on /dashboard, and await auth() in the page returns their userId.

Example 2: "Only org admins can create projects, and mirror users into Postgres"

Server action:

'use server';
import { auth } from '@clerk/nextjs/server';

export async function createProject(name: string) {
  const { userId, orgId, has } = await auth();
  if (!orgId || !has({ role: 'org:admin' })) throw new Error('Forbidden');
  return db.projects.create({ data: { name, orgId, createdBy: userId } });
}

Add the /api/webhooks/clerk route from step 6, set CLERK_WEBHOOK_SIGNING_SECRET=whsec_..., and subscribe to user.created and user.deleted. Result: a member calling createProject gets "Forbidden", an admin gets the new row, and every sign-up appears in your users table within seconds.

Guidelines

  • Middleware is a convenience layer, not the only barrier: check auth() again in server components, route handlers and server actions.
  • Verify every webhook signature (verifyWebhook); an unverified endpoint lets anyone forge user events.
  • Webhooks are eventually consistent and can arrive out of order or twice: make handlers idempotent (upsert by clerkId). Keep a local copy of users and orgs rather than calling Clerk's Backend API on every request (rate limited).
  • Never commit CLERK_SECRET_KEY or the webhook signing secret; only the publishable key is public.
  • If your app uses Next.js 16, rename middleware.ts to proxy.ts; otherwise clerkMiddleware never runs and auth() fails to find it. Clerk Core 3 does not support Next.js 13 or 14.
  • hidePersonal on <OrganizationSwitcher> removes personal workspaces for team-only products.
  • Not a fit if you need a fully self-hosted identity provider; look at Keycloak or Auth.js instead.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Scripts and configures production rendering in Autodesk 3ds Max with the V-Ray and Corona renderers: output size and files, render elements, denoising, light mix, batch and command-line rendering, and network rendering. Use when a user asks to set up a production render, render several cameras in one batch, render from the command line or on a render farm, add render passes for compositing, or cut render time for archviz and product shots.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

Covers scripting Autodesk 3ds Max, the 3D modeling and rendering application, with MAXScript and Python (pymxs): scene manipulation, object creation, material assignment, camera and light setup, batch operations, and file I/O. Use when tasks involve automating repetitive 3ds Max workflows, batch processing scenes, running scripts headless with 3dsmaxbatch, creating custom tools, or scripting scene setup for archviz, product visualization, or VFX.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

3proxy

無料

3proxy is a small open-source proxy server that runs HTTP/HTTPS, SOCKS4/5, SNI and TCP/UDP port-mapping proxies from one config file. Use when a user asks to set up an HTTP or SOCKS5 proxy, add proxy users and passwords, write 3proxy access rules, chain or rotate upstream (parent) proxies, limit bandwidth, connections or monthly traffic per user, run 3proxy in Docker, or fix a 3proxy.cfg that will not start.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

Builds Agent2Agent (A2A) servers and clients, the open protocol (originally from Google, now under the Linux Foundation) that lets AI agents from different frameworks call each other. Use when the user wants to create an A2A-compliant agent, build an Agent Card, implement task management, connect agents across frameworks, set up agent discovery, handle streaming responses, implement push notifications, or orchestrate multi-agent workflows. Trigger words: a2a, agent to agent, agent2agent, a2a protocol, a2a server, a2a client, agent card, agent interoperability, agent collaboration, multi-agent, agent discovery, a2a sdk, a2a task.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

Plans a controlled experiment (A/B test) so its result can be trusted: writes the hypothesis, picks one primary metric and the guardrails, computes sample size and run time, specifies how visitors are assigned and when exposure is logged, and reads out the result with a confidence interval. Use when someone says "set up an A/B test", "split test this page", "how many visitors do I need", "how long should the experiment run", "is this result significant", "can I stop the test early", or wants to test a headline, price, layout or onboarding change against the current version.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

ably

無料

Ably is a hosted realtime messaging service: clients publish and subscribe to named channels over WebSockets, see who is present, replay message history, and resume after a dropped connection. Use when a user asks to "add realtime updates", "push live notifications to the browser", "show who is online", "add a chat room with typing indicators", "publish from a serverless function", or "authenticate Ably clients without exposing the API key". Covers the ably 2.x JavaScript SDK (Realtime and REST), JWT token authentication, presence, history and rewind, batch publishing, and the @ably/chat 1.x SDK.

日本語の概要は準備中です。原文の説明を表示しています。

TerminalSkills/skills1652026年10月4日 更新

TerminalSkills のスキルをすべて見る

このスキルの問題を報告する