workos-authkit-nextjs

📁 workos/cli 📅 7 days ago
10
总安装量
4
周安装量
#29608
全站排名
安装命令
npx skills add https://github.com/workos/cli --skill workos-authkit-nextjs

Agent 安装分布

amp 4
opencode 4
kimi-cli 4
codex 4
gemini-cli 4

Skill 文档

WorkOS AuthKit for Next.js

Step 1: Fetch SDK Documentation (BLOCKING)

STOP. Do not proceed until complete.

WebFetch: https://github.com/workos/authkit-nextjs/blob/main/README.md

The README is the source of truth. If this skill conflicts with README, follow README.

Step 2: Pre-Flight Validation

Project Structure

  • Confirm next.config.js or next.config.mjs exists
  • Confirm package.json contains "next" dependency

Environment Variables

Check .env.local for:

  • WORKOS_API_KEY – starts with sk_
  • WORKOS_CLIENT_ID – starts with client_
  • NEXT_PUBLIC_WORKOS_REDIRECT_URI – valid callback URL
  • WORKOS_COOKIE_PASSWORD – 32+ characters

Step 3: Install SDK

Detect package manager, install SDK package from README.

Verify: SDK package exists in node_modules before continuing.

Step 4: Version Detection (Decision Tree)

Read Next.js version from package.json:

Next.js version?
  |
  +-- 16+ --> Create proxy.ts at project root
  |
  +-- 15   --> Create middleware.ts (cookies() is async - handlers must await)
  |
  +-- 13-14 --> Create middleware.ts (cookies() is sync)

Critical: File MUST be at project root (or src/ if using src directory). Never in app/.

Next.js 15+ async note: All route handlers and middleware accessing cookies must be async and properly await cookie operations. This is a breaking change from Next.js 14.

Middleware/proxy code: See README for authkitMiddleware() export pattern.

Existing Middleware (IMPORTANT)

If middleware.ts already exists with custom logic (rate limiting, logging, headers, etc.), use the authkit() composable function instead of authkitMiddleware.

Pattern for composing with existing middleware:

import { NextRequest, NextResponse } from 'next/server';
import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';

export default async function middleware(request: NextRequest) {
  // 1. Get auth session and headers from AuthKit
  const { session, headers, authorizationUrl } = await authkit(request);
  const { pathname } = request.nextUrl;

  // 2. === YOUR EXISTING MIDDLEWARE LOGIC ===
  // Rate limiting, logging, custom headers, etc.
  const rateLimitResult = checkRateLimit(request);
  if (!rateLimitResult.allowed) {
    return new NextResponse('Too Many Requests', { status: 429 });
  }

  // 3. Protect routes - redirect to auth if needed
  if (pathname.startsWith('/dashboard') && !session.user && authorizationUrl) {
    return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
  }

  // 4. Continue with AuthKit headers properly handled
  return handleAuthkitHeaders(request, headers);
}

Key functions:

  • authkit(request) – Returns { session, headers, authorizationUrl } for composition
  • handleAuthkitHeaders(request, headers, options?) – Ensures AuthKit headers pass through correctly
  • For rewrites, use partitionAuthkitHeaders() and applyResponseHeaders() (see README)

Critical: Always return via handleAuthkitHeaders() to ensure withAuth() works in pages.

Step 5: Create Callback Route

Parse NEXT_PUBLIC_WORKOS_REDIRECT_URI to determine route path:

URI path          --> Route location
/auth/callback    --> app/auth/callback/route.ts
/callback         --> app/callback/route.ts

Use handleAuth() from SDK. Do not write custom OAuth logic.

CRITICAL for Next.js 15+: The route handler MUST be async and properly await handleAuth():

// CORRECT - Next.js 15+ requires async route handlers
export const GET = handleAuth();

// If handleAuth returns a function, ensure it's awaited in request context

Check README for exact usage. If build fails with “cookies outside request scope”, the handler is likely missing async/await.

Step 6: Provider Setup (REQUIRED)

CRITICAL: You MUST wrap the app in AuthKitProvider in app/layout.tsx.

This is required for:

  • Client-side auth state via useAuth() hook
  • Consistent auth UX across client/server boundaries
  • Proper migration from Auth0 (which uses client-side auth)
// app/layout.tsx
import { AuthKitProvider } from '@workos-inc/authkit-nextjs';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <AuthKitProvider>{children}</AuthKitProvider>
      </body>
    </html>
  );
}

Check README for exact import path – it may be a subpath export like @workos-inc/authkit-nextjs/components.

Do NOT skip this step even if using server-side auth patterns elsewhere.

Step 7: UI Integration

Add auth UI to app/page.tsx using SDK functions. See README for getUser, getSignInUrl, signOut usage.

Verification Checklist (ALL MUST PASS)

Run these commands to confirm integration. Do not mark complete until all pass:

# 1. Check middleware/proxy exists (one should match)
ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null

# 2. CRITICAL: Check AuthKitProvider is in layout (REQUIRED)
grep "AuthKitProvider" app/layout.tsx || echo "FAIL: AuthKitProvider missing from layout"

# 3. Check callback route exists
find app -name "route.ts" -path "*/callback/*"

# 4. Build succeeds
npm run build

If check #2 fails: Go back to Step 6 and add AuthKitProvider. This is not optional.

Error Recovery

“cookies was called outside a request scope” (Next.js 15+)

Most common cause: Route handler not properly async or missing await.

Fix for callback route:

  1. Check that handleAuth() is exported directly: export const GET = handleAuth();
  2. If using custom wrapper, ensure it’s async and awaits any cookie operations
  3. Verify authkit-nextjs SDK version supports Next.js 15+ (check README for compatibility)
  4. Never call cookies() at module level – only inside request handlers

This error causes OAuth codes to expire (“invalid_grant”), so fix the handler first.

“middleware.ts not found”

  • Check: File at project root or src/, not inside app/
  • Check: Filename matches Next.js version (proxy.ts for 16+, middleware.ts for 13-15)

“Cannot use getUser in client component”

  • Check: Component has no 'use client' directive, or
  • Check: Move auth logic to server component/API route

“Module not found” for SDK import

  • Check: SDK installed before writing imports
  • Check: SDK package directory exists in node_modules

“withAuth route not covered by middleware”

  • Check: Middleware/proxy file exists at correct location
  • Check: Matcher config includes the route path

Build fails after AuthKitProvider

  • Check: README for correct import path (may be subpath export)
  • Check: No client/server boundary violations

NEXTPUBLIC prefix issues

  • Client components need NEXT_PUBLIC_* prefix
  • Server components use plain env var names