workos-authkit-nextjs

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

WorkOS AuthKit for Next.js

适用于Next.js的WorkOS AuthKit

Step 1: Fetch SDK Documentation (BLOCKING)

步骤1:获取SDK文档(阻塞操作)

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.
停止操作。完成此步骤前请勿继续。
WebFetch:
https://github.com/workos/authkit-nextjs/blob/main/README.md
README是权威来源。如果本技能内容与README冲突,请以README为准。

Step 2: Pre-Flight Validation

步骤2:前期验证检查

Project Structure

项目结构

  • Confirm
    next.config.js
    or
    next.config.mjs
    exists
  • Confirm
    package.json
    contains
    "next"
    dependency
  • 确认项目中存在
    next.config.js
    next.config.mjs
  • 确认
    package.json
    中包含
    "next"
    依赖

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
检查
.env.local
文件中是否存在以下变量:
  • WORKOS_API_KEY
    - 以
    sk_
    开头
  • WORKOS_CLIENT_ID
    - 以
    client_
    开头
  • NEXT_PUBLIC_WORKOS_REDIRECT_URI
    - 有效的回调URL
  • WORKOS_COOKIE_PASSWORD
    - 长度不少于32个字符

Step 3: Install SDK

步骤3:安装SDK

Detect package manager, install SDK package from README.
Verify: SDK package exists in node_modules before continuing.
检测包管理器,按照README中的说明安装SDK包。
验证: 继续操作前,请确认SDK包已存在于node_modules目录中。

Step 4: Version Detection (Decision Tree)

步骤4:版本检测(决策树)

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.
package.json
中读取Next.js版本:
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)
关键注意事项: 文件必须位于项目根目录(如果使用src目录,则放在
src/
下)。绝对不能放在
app/
目录中。
Next.js 15+异步注意事项: 所有访问cookies的路由处理器和中间件必须是异步的,并且要正确等待cookie操作完成。这是Next.js 14到15的破坏性变更。
中间件/代理代码:请查看README中的
authkitMiddleware()
导出模式。

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:
typescript
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.
如果
middleware.ts
已存在且包含自定义逻辑(限流、日志、请求头处理等),请使用**
authkit()
组合函数**替代
authkitMiddleware
与现有中间件组合的模式:
typescript
import { NextRequest, NextResponse } from 'next/server';
import { authkit, handleAuthkitHeaders } from '@workos-inc/authkit-nextjs';

export default async function middleware(request: NextRequest) {
  // 1. 从AuthKit获取认证会话和请求头
  const { session, headers, authorizationUrl } = await authkit(request);
  const { pathname } = request.nextUrl;

  // 2. === 您的现有中间件逻辑 ===
  // 限流、日志、自定义请求头等
  const rateLimitResult = checkRateLimit(request);
  if (!rateLimitResult.allowed) {
    return new NextResponse('Too Many Requests', { status: 429 });
  }

  // 3. 保护路由 - 如需认证则重定向
  if (pathname.startsWith('/dashboard') && !session.user && authorizationUrl) {
    return handleAuthkitHeaders(request, headers, { redirect: authorizationUrl });
  }

  // 4. 正确处理AuthKit请求头后继续
  return handleAuthkitHeaders(request, headers);
}
核心函数:
  • authkit(request)
    - 返回
    { session, headers, authorizationUrl }
    用于组合逻辑
  • handleAuthkitHeaders(request, headers, options?)
    - 确保AuthKit请求头正确传递
  • 如需重写路由,请使用
    partitionAuthkitHeaders()
    applyResponseHeaders()
    (详见README)
关键注意事项: 必须通过
handleAuthkitHeaders()
返回结果,以确保页面中的
withAuth()
正常工作。

Step 5: Create Callback Route

步骤5:创建回调路由

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():
typescript
// 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.
解析
NEXT_PUBLIC_WORKOS_REDIRECT_URI
以确定路由路径:
URI路径          --> 路由位置
/auth/callback    --> app/auth/callback/route.ts
/callback         --> app/callback/route.ts
使用SDK中的
handleAuth()
。请勿编写自定义OAuth逻辑。
Next.js 15+关键要求: 路由处理器必须是异步的,并且要正确等待handleAuth()执行完成:
typescript
// 正确写法 - Next.js 15+要求异步路由处理器
export const GET = handleAuth();

// 如果handleAuth返回一个函数,请确保在请求上下文中等待其执行
请查看README获取确切用法。如果构建失败并提示"cookies outside request scope",则说明处理器可能缺少async/await。

Step 6: Provider Setup (REQUIRED)

步骤6:Provider配置(必填)

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)
tsx
// 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.
关键注意事项: 您必须在
app/layout.tsx
中使用
AuthKitProvider
包裹整个应用。
这是以下功能的必要条件:
  • 通过
    useAuth()
    钩子在客户端获取认证状态
  • 在客户端/服务端边界保持一致的认证用户体验
  • 从Auth0平滑迁移(Auth0使用客户端认证)
tsx
// 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>
  );
}
请查看README确认确切的导入路径 - 它可能是子路径导出,例如
@workos-inc/authkit-nextjs/components
请勿跳过此步骤,即使您在其他地方使用了服务端认证模式。

Step 7: UI Integration

步骤7:UI集成

Add auth UI to
app/page.tsx
using SDK functions. See README for
getUser
,
getSignInUrl
,
signOut
usage.
使用SDK函数在
app/page.tsx
中添加认证UI。请查看README中
getUser
getSignInUrl
signOut
的用法。

Verification Checklist (ALL MUST PASS)

验证清单(必须全部通过)

Run these commands to confirm integration. Do not mark complete until all pass:
bash
undefined
运行以下命令确认集成是否成功。必须全部通过后才能标记完成:
bash
undefined

1. Check middleware/proxy exists (one should match)

1. 检查中间件/代理文件是否存在(以下其中一个应存在)

ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null
ls proxy.ts middleware.ts src/proxy.ts src/middleware.ts 2>/dev/null

2. CRITICAL: Check AuthKitProvider is in layout (REQUIRED)

2. 关键检查:确认AuthKitProvider已添加到布局中(必填)

grep "AuthKitProvider" app/layout.tsx || echo "FAIL: AuthKitProvider missing from layout"
grep "AuthKitProvider" app/layout.tsx || echo "失败:布局中缺少AuthKitProvider"

3. Check callback route exists

3. 检查回调路由是否存在

find app -name "route.ts" -path "/callback/"
find app -name "route.ts" -path "/callback/"

4. Build succeeds

4. 构建是否成功

npm run build

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

**如果检查2失败:** 返回步骤6添加AuthKitProvider。此步骤为必填项,不可省略。

Error Recovery

错误排查

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

"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.
最常见原因: 路由处理器未正确设置为异步,或缺少await。
回调路由的修复方法:
  1. 确认
    handleAuth()
    是直接导出的:
    export const GET = handleAuth();
  2. 如果使用自定义包装函数,请确保它是
    async
    的,并且等待所有cookie操作完成
  3. 验证authkit-nextjs SDK版本是否支持Next.js 15+(查看README确认兼容性)
  4. 绝对不要在模块级别调用
    cookies()
    - 只能在请求处理器内部调用
此错误会导致OAuth代码过期("invalid_grant"),因此请优先修复处理器。

"middleware.ts not found"

"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)
  • 检查:文件是否位于项目根目录或
    src/
    下,而不是
    app/
    目录中
  • 检查:文件名是否与Next.js版本匹配(16+使用proxy.ts,13-15使用middleware.ts)

"Cannot use getUser in client component"

"Cannot use getUser in client component"

  • Check: Component has no
    'use client'
    directive, or
  • Check: Move auth logic to server component/API route
  • 检查:组件是否没有
    'use client'
    指令,或者
  • 检查:将认证逻辑迁移到服务端组件/API路由

"Module not found" for SDK import

"Module not found" for SDK import

  • Check: SDK installed before writing imports
  • Check: SDK package directory exists in node_modules
  • 检查:编写导入语句前是否已安装SDK
  • 检查:node_modules中是否存在SDK包目录

"withAuth route not covered by middleware"

"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

添加AuthKitProvider后构建失败

  • Check: README for correct import path (may be subpath export)
  • Check: No client/server boundary violations
  • 检查:README中的正确导入路径(可能是子路径导出)
  • 检查:是否存在客户端/服务端边界冲突

NEXTPUBLIC prefix issues

NEXT_PUBLIC前缀问题

  • Client components need
    NEXT_PUBLIC_*
    prefix
  • Server components use plain env var names
  • 客户端组件需要
    NEXT_PUBLIC_*
    前缀
  • 服务端组件使用普通的环境变量名称