Token导航 LogoToken导航TokenDH.com
开发敏感数据github未标认证来源可访问clear审计异常

auth-js授权 js

Agent Skill

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

总安装

791

周安装

32

GitHub Stars

14

下载量

248
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:auth-js(授权 js)
来源仓库:https://github.com/jackspace/claudeskillz
仓库路径:skills/auth-js
安装命令:
npx skills add https://github.com/jackspace/claudeskillz --skill auth-js
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/jackspace/claudeskillz --skill auth-js

简介

auth-js 提供 Auth.js v5 在生产环境经过验证的配置模式,支持 Next.js 和 Cloudflare Workers。

  • 适用于需要 OAuth 集成、会话管理和 JWT 支持的现代 Web 应用。
  • 使用前必须阅读 references/common-errors.md 规避已知问题,如 CSRF 配置错误。
  • 安装前需确认用户已告知 Claude 正在使用此技能,以便获得针对性建议。
  • 注意:本技能强调“不要猜测”,不确定时应返回文档查询而非假设实现。

SKILL.md

Auth.js v5 Authentication Stack

Production-tested: Multiple Next.js and Cloudflare Workers projects Last Updated: 2025-10-26 Status: Production Ready ✅ Official Docs: https://authjs.dev


⚠️ BEFORE YOU START (READ THIS!)

CRITICAL FOR AI AGENTS: If you're Claude Code helping a user set up Auth.js:

  1. Explicitly state you're using this skill at the start of the conversation
  2. Reference patterns from the skill rather than general knowledge
  3. Prevent known issues listed in references/common-errors.md
  4. Don't guess - if unsure, check the skill documentation

USER ACTION REQUIRED: Tell Claude to check this skill first!

Say: "I'm setting up Auth.js - check the auth-js skill first"

Why This Matters (Real-World Results)

Without skill activation:

  • ❌ Setup time: ~15 minutes
  • ❌ Errors encountered: 3-5 (AUTH_SECRET, CallbackRouteError, edge issues)
  • ❌ Manual fixes needed: 3-4 commits
  • ❌ Token usage: ~15k
  • ❌ User confidence: Multiple debugging sessions

With skill activation:

  • ✅ Setup time: ~3 minutes
  • ✅ Errors encountered: 0
  • ✅ Manual fixes needed: 0
  • ✅ Token usage: ~6k (60% reduction)
  • ✅ User confidence: Instant success

Known Issues This Skill Prevents

  1. Missing AUTH_SECRET → JWEDecryptionFailed error
  2. CallbackRouteError → Throwing in authorize() instead of returning null
  3. Route not found → Incorrect file path for [...nextauth].js
  4. Edge incompatibility → Using database session without edge-compatible adapter
  5. PKCE errors → OAuth provider misconfiguration
  6. Session not updating → Missing middleware
  7. v5 migration issues → Namespace changes, JWT salt changes
  8. D1 binding errors → Wrangler configuration mismatch
  9. Credentials with database → Incompatible session strategy
  10. Production deployment failures → Missing environment variables
  11. Token refresh errors → Incorrect callback implementation
  12. JSON expected but HTML received → Rewrites configuration in Next.js 15

All of these are handled automatically when the skill is active.


Table of Contents

  1. Quick Start - Next.js
  2. Quick Start - Cloudflare Workers
  3. Core Concepts
  4. Session Strategies
  5. Provider Setup
  6. Database Adapters
  7. Middleware Patterns
  8. Advanced Features
  9. Critical Rules
  10. Common Errors & Fixes
  11. Templates Reference

Quick Start: Next.js

Prerequisites

# Next.js 15+ with App Router
npm create next-app@latest my-app
cd my-app

Installation

npm install next-auth@latest
npm install @auth/core@latest

# Choose your database adapter (if using database sessions)
npm install @auth/prisma-adapter  # For PostgreSQL/MySQL
npm install @auth/d1-adapter      # For Cloudflare D1

1. Create Auth Configuration

Option A: Simple Setup (JWT sessions, no database)

// auth.ts
import NextAuth from "next-auth"
import GitHub from "next-auth/providers/github"

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [
    GitHub({
      clientId: process.env.AUTH_GITHUB_ID,
      clientSecret: process.env.AUTH_GITHUB_SECRET,
    }),
  ],
})

Option B: Edge-Compatible Setup (recommended for middleware)

// auth.config.ts (edge-compatible, no database)
import type { NextAuthConfig } from "next-auth"
import GitHub from "next-auth/providers/github"

export default {
  providers: [
    GitHub({
      clientId: process.env.AUTH_GITHUB_ID,
      clientSecret: process.env.AUTH_GITHUB_SECRET,
    }),
  ],
} satisfies NextAuthConfig
// auth.ts (full config with database)
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
import authConfig from "./auth.config"

const prisma = new PrismaClient()

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" }, // CRITICAL: Force JWT for edge compatibility
  ...authConfig,
})

2. Create API Route Handler

// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth"

export const { GET, POST } = handlers

3. Add Middleware (Optional but Recommended)

// middleware.ts
export { auth as middleware } from "@/auth"

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

4. Environment Variables

# .env.local
AUTH_SECRET=your-secret-here  # Generate with: npx auth secret
AUTH_GITHUB_ID=your_github_client_id
AUTH_GITHUB_SECRET=your_github_client_secret

# CRITICAL: In production, AUTH_SECRET is REQUIRED

5. Use in Components

Server Component (App Router):

import { auth } from "@/auth"

export default async function Dashboard() {
  const session = await auth()

  if (!session?.user) {
    return <p>Not authenticated</p>
  }

  return <p>Welcome {session.user.name}</p>
}

Client Component:

"use client"
import { useSession } from "next-auth/react"

export default function ClientDashboard() {
  const { data: session, status } = useSession()

  if (status === "loading") return <p>Loading...</p>
  if (status === "unauthenticated") return <p>Not authenticated</p>

  return <p>Welcome {session?.user?.name}</p>
}

6. Sign In / Sign Out

import { signIn, signOut } from "@/auth"

export function SignIn() {
  return (
    <form
      action={async () => {
        "use server"
        await signIn("github")
      }}
    >
      <button type="submit">Sign in with GitHub</button>
    </form>
  )
}

export function SignOut() {
  return (
    <form
      action={async () => {
        "use server"
        await signOut()
      }}
    >
      <button type="submit">Sign Out</button>
    </form>
  )
}

Quick Start: Cloudflare Workers

Prerequisites

npm create cloudflare@latest my-auth-worker
cd my-auth-worker

Installation

npm install @auth/core@latest
npm install @auth/d1-adapter@latest
npm install hono

1. Configure Wrangler with D1

// wrangler.jsonc
{
  "name": "my-auth-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-10-26",
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "auth_db",
      "database_id": "your-database-id"
    }
  ]
}

2. Create D1 Database

# Create database
npx wrangler d1 create auth_db

# Copy the database_id to wrangler.jsonc

# Create tables
npx wrangler d1 execute auth_db --file=./schema.sql

schema.sql:

-- See templates/cloudflare-workers/schema.sql for complete schema
CREATE TABLE users (
  id TEXT PRIMARY KEY,
  name TEXT,
  email TEXT UNIQUE NOT NULL,
  emailVerified INTEGER,
  image TEXT
);

CREATE TABLE accounts (
  id TEXT PRIMARY KEY,
  userId TEXT NOT NULL,
  type TEXT NOT NULL,
  provider TEXT NOT NULL,
  providerAccountId TEXT NOT NULL,
  refresh_token TEXT,
  access_token TEXT,
  expires_at INTEGER,
  token_type TEXT,
  scope TEXT,
  id_token TEXT,
  session_state TEXT,
  FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE,
  UNIQUE(provider, providerAccountId)
);

CREATE TABLE sessions (
  id TEXT PRIMARY KEY,
  userId TEXT NOT NULL,
  expires INTEGER NOT NULL,
  sessionToken TEXT UNIQUE NOT NULL,
  FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE
);

CREATE TABLE verification_tokens (
  identifier TEXT NOT NULL,
  token TEXT UNIQUE NOT NULL,
  expires INTEGER NOT NULL,
  PRIMARY KEY (identifier, token)
);

3. Create Worker with Auth

// src/index.ts
import { Hono } from 'hono'
import { Auth } from '@auth/core'
import { D1Adapter } from '@auth/d1-adapter'
import GitHub from '@auth/core/providers/github'

type Bindings = {
  DB: D1Database
  AUTH_SECRET: string
  AUTH_GITHUB_ID: string
  AUTH_GITHUB_SECRET: string
}

const app = new Hono<{ Bindings: Bindings }>()

app.all('/api/auth/*', async (c) => {
  const response = await Auth(c.req.raw, {
    adapter: D1Adapter(c.env.DB),
    providers: [
      GitHub({
        clientId: c.env.AUTH_GITHUB_ID,
        clientSecret: c.env.AUTH_GITHUB_SECRET,
      }),
    ],
    secret: c.env.AUTH_SECRET,
    trustHost: true,
  })
  return response
})

app.get('/', async (c) => {
  // Example: Get session
  const session = await Auth(c.req.raw, {
    adapter: D1Adapter(c.env.DB),
    providers: [],
    secret: c.env.AUTH_SECRET,
  })

  return c.json({ session })
})

export default app

4. Environment Variables

# Add secrets to Cloudflare Workers
npx wrangler secret put AUTH_SECRET
npx wrangler secret put AUTH_GITHUB_ID
npx wrangler secret put AUTH_GITHUB_SECRET

5. Deploy

npx wrangler deploy

Core Concepts

Session Strategies

Auth.js v5 supports two session strategies:

  1. JWT (JSON Web Token) - Default when no adapter configured

- ✅ Works in edge runtime - ✅ No database queries for sessions - ✅ Fast and scalable - ❌ Cannot invalidate sessions server-side - ❌ Token size limits

  1. Database - Default when adapter configured

- ✅ Full session control (invalidate, extend) - ✅ Audit trail in database - ✅ No token size limits - ❌ Requires database query per request - ❌ Not compatible with all edge runtimes

Decision Matrix:

Use CaseRecommended StrategyReason
Next.js App RouterJWTEdge runtime compatibility
Cloudflare WorkersJWT or Database (with D1)D1 is edge-compatible
Traditional Node.jsDatabaseFull session control
High securityDatabaseCan invalidate sessions
Read-only sessionsJWTNo database overhead

See references/session-strategies.md for detailed comparison.


Session Strategies

JWT Sessions (Default)

When to use:

  • Edge runtime deployment (Cloudflare Workers, Vercel Edge)
  • No database adapter configured
  • Read-only session data
  • High-traffic applications (no DB queries)

Configuration:

export const { handlers, auth } = NextAuth({
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  providers: [GitHub],
})

⚠️ CRITICAL: Even if you have an adapter configured, you MUST explicitly set strategy: "jwt" for edge runtime compatibility!

Database Sessions

When to use:

  • Node.js runtime (not edge)
  • Need to invalidate sessions server-side
  • Compliance requirements (audit trail)
  • Session data larger than JWT limits

Configuration:

import { PrismaAdapter } from "@auth/prisma-adapter"

export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: {
    strategy: "database",
    maxAge: 30 * 24 * 60 * 60,
    updateAge: 24 * 60 * 60, // Update session every 24 hours
  },
  providers: [GitHub],
})

⚠️ Edge Runtime Limitation:

If your adapter is NOT edge-compatible, you CANNOT use database sessions in edge runtime (middleware). Split your config:

// auth.config.ts (edge-compatible)
export default {
  providers: [GitHub],
} satisfies NextAuthConfig

// auth.ts (full config with database)
import authConfig from "./auth.config"

export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma), // Not edge-compatible
  session: { strategy: "jwt" }, // FORCE JWT for middleware
  ...authConfig,
})

Provider Setup

OAuth Providers (GitHub, Google, etc.)

GitHub:

import GitHub from "next-auth/providers/github"

export const { handlers, auth } = NextAuth({
  providers: [
    GitHub({
      clientId: process.env.AUTH_GITHUB_ID,
      clientSecret: process.env.AUTH_GITHUB_SECRET,
    }),
  ],
})

Google (with token refresh):

import Google from "next-auth/providers/google"

export const { handlers, auth } = NextAuth({
  providers: [
    Google({
      clientId: process.env.AUTH_GOOGLE_ID,
      clientSecret: process.env.AUTH_GOOGLE_SECRET,
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
        },
      },
    }),
  ],
})

See templates/providers/oauth-github-google.ts for complete example.

Credentials Provider (Email/Password)

⚠️ CRITICAL: The Credentials provider ONLY supports JWT sessions!

import Credentials from "next-auth/providers/credentials"
import { z } from "zod"
import bcrypt from "bcryptjs"

const signInSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
})

export const { handlers, auth } = NextAuth({
  providers: [
    Credentials({
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      authorize: async (credentials) => {
        try {
          const { email, password } = await signInSchema.parseAsync(credentials)

          // Fetch user from database
          const user = await db.user.findUnique({ where: { email } })

          if (!user || !user.password) {
            // CRITICAL: Return null, DON'T throw
            return null
          }

          const passwordMatch = await bcrypt.compare(password, user.password)

          if (!passwordMatch) {
            return null
          }

          // Return user object
          return {
            id: user.id,
            email: user.email,
            name: user.name,
          }
        } catch (error) {
          // CRITICAL: Return null on error, DON'T throw
          console.error("Auth error:", error)
          return null
        }
      },
    }),
  ],
})

⚠️ CRITICAL RULES:

  1. NEVER throw errors in authorize() - always return null
  2. Why? Throwing errors causes CallbackRouteError instead of CredentialsSignin
  3. Always validate with Zod before checking credentials
  4. Hash passwords with bcrypt, never store plain text

See templates/providers/credentials.ts for complete example.

Magic Link Provider (Passwordless)

⚠️ CRITICAL: Magic links REQUIRE a database adapter!

import Resend from "next-auth/providers/resend"
import { PrismaAdapter } from "@auth/prisma-adapter"

export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma), // REQUIRED
  providers: [
    Resend({
      apiKey: process.env.AUTH_RESEND_KEY,
      from: "noreply@example.com",
    }),
  ],
})

See templates/providers/magic-link-resend.ts for complete example.


Database Adapters

Cloudflare D1 Adapter

Installation:

npm install @auth/d1-adapter@latest

Wrangler Configuration:

// wrangler.jsonc
{
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "auth_db",
      "database_id": "your-database-id"
    }
  ]
}

Usage:

import { D1Adapter } from "@auth/d1-adapter"

// Cloudflare Workers
const app = new Hono<{ Bindings: { DB: D1Database } }>()

app.all('/api/auth/*', async (c) => {
  return await Auth(c.req.raw, {
    adapter: D1Adapter(c.env.DB),
    providers: [GitHub],
  })
})

// Next.js (with D1 via wrangler)
export const { handlers, auth } = NextAuth({
  adapter: D1Adapter(env.DB),
  session: { strategy: "jwt" }, // Recommended for edge
  providers: [GitHub],
})

Database Schema:

See templates/cloudflare-workers/schema.sql for complete schema.

Edge Compatibility: ✅ D1 is fully edge-compatible!

Prisma Adapter (PostgreSQL/MySQL)

Installation:

npm install @auth/prisma-adapter@latest
npm install @prisma/client@latest
npm install -D prisma@latest

Prisma Schema:

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String    @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
}

model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String? @db.Text
  access_token      String? @db.Text
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String? @db.Text
  session_state     String?

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime

  @@unique([identifier, token])
}

Usage:

import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"

const prisma = new PrismaClient()

export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" }, // For edge compatibility
  providers: [GitHub],
})

Edge Compatibility: ❌ Prisma is NOT edge-compatible by default

Workaround: Use Prisma Accelerate or Hyperdrive for edge compatibility, OR force JWT sessions and don't use the adapter in middleware.

See templates/database-adapters/prisma-postgresql.ts for complete example.


Middleware Patterns

Session Keep-Alive

// middleware.ts
export { auth as middleware } from "@/auth"

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

This automatically updates session expiry on every request.

Route Protection

// middleware.ts
import { auth } from "@/auth"
import { NextResponse } from "next/server"

export default auth((req) => {
  const { pathname } = req.nextUrl

  // Protect /dashboard routes
  if (pathname.startsWith("/dashboard")) {
    if (!req.auth) {
      const loginUrl = new URL("/login", req.url)
      loginUrl.searchParams.set("callbackUrl", pathname)
      return NextResponse.redirect(loginUrl)
    }
  }

  return NextResponse.next()
})

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

Role-Based Access Control (RBAC)

// auth.ts
export const { handlers, auth } = NextAuth({
  providers: [GitHub],
  callbacks: {
    async jwt({ token, user }) {
      // Add role to JWT on sign in
      if (user) {
        token.role = user.role
      }
      return token
    },
    async session({ session, token }) {
      // Expose role to session
      if (session.user) {
        session.user.role = token.role
      }
      return session
    },
  },
})
// middleware.ts
import { auth } from "@/auth"
import { NextResponse } from "next/server"

export default auth((req) => {
  const { pathname } = req.nextUrl

  // Protect /admin routes (require admin role)
  if (pathname.startsWith("/admin")) {
    if (!req.auth || req.auth.user.role !== "admin") {
      return NextResponse.redirect(new URL("/unauthorized", req.url))
    }
  }

  return NextResponse.next()
})

See references/middleware-patterns.md and templates/advanced/role-based-access.ts for complete examples.


Advanced Features

JWT Callbacks (Custom Claims)

export const { handlers, auth } = NextAuth({
  providers: [GitHub],
  callbacks: {
    async jwt({ token, user, account }) {
      // On sign in
      if (user) {
        token.id = user.id
        token.role = user.role
      }

      // On subsequent requests
      return token
    },
    async session({ session, token }) {
      // Expose custom claims to session
      session.user.id = token.id
      session.user.role = token.role
      return session
    },
  },
})

Token Refresh (OAuth)

Google OAuth with token refresh:

import Google from "next-auth/providers/google"

export const { handlers, auth } = NextAuth({
  providers: [
    Google({
      authorization: {
        params: {
          prompt: "consent",
          access_type: "offline",
          response_type: "code",
        },
      },
    }),
  ],
  callbacks: {
    async jwt({ token, account }) {
      // First-time login, save tokens
      if (account) {
        return {
          ...token,
          access_token: account.access_token,
          expires_at: account.expires_at,
          refresh_token: account.refresh_token,
        }
      }

      // Subsequent logins, check if token expired
      if (Date.now() < token.expires_at * 1000) {
        return token
      }

      // Token expired, refresh it
      try {
        const response = await fetch("https://oauth2.googleapis.com/token", {
          method: "POST",
          body: new URLSearchParams({
            client_id: process.env.AUTH_GOOGLE_ID!,
            client_secret: process.env.AUTH_GOOGLE_SECRET!,
            grant_type: "refresh_token",
            refresh_token: token.refresh_token!,
          }),
        })

        const newTokens = await response.json()

        return {
          ...token,
          access_token: newTokens.access_token,
          expires_at: Math.floor(Date.now() / 1000 + newTokens.expires_in),
          refresh_token: newTokens.refresh_token ?? token.refresh_token,
        }
      } catch (error) {
        console.error("Token refresh error:", error)
        token.error = "RefreshTokenError"
        return token
      }
    },
    async session({ session, token }) {
      session.error = token.error
      return session
    },
  },
})

See templates/advanced/jwt-refresh-tokens.ts for complete example.


Critical Rules

✅ Always Do:

  1. Set AUTH_SECRET in production # Generate secret npx auth secret # Add to.env.local AUTH_SECRET=your-generated-secret
  2. Return null (not throw) in Credentials authorize() authorize: async (credentials) => {if (!validUser) {return null // ✅ Correct // throw new Error("Invalid") // ❌ WRONG - causes CallbackRouteError}}
  3. Use adapter for Magic Links export const {handlers, auth} = NextAuth({adapter: PrismaAdapter(prisma), // REQUIRED for magic links providers: [Resend],})
  4. Split config for edge compatibility // auth.config.ts (edge-compatible) export default {providers: [GitHub]} // auth.ts (full config with database) export const {handlers, auth} = NextAuth({adapter: PrismaAdapter(prisma), session: {strategy: "jwt"}, // Force JWT for edge...authConfig,})
  5. Force JWT sessions when using non-edge adapter export const {handlers, auth} = NextAuth({adapter: PrismaAdapter(prisma), // Not edge-compatible session: {strategy: "jwt"}, // CRITICAL})

❌ Never Do:

  1. Deploy without AUTH_SECRET // WRONG - will fail in production // Missing AUTH_SECRET environment variable
  2. Throw errors in authorize() authorize: async (credentials) => {throw new Error("Invalid credentials") // ❌ Causes CallbackRouteError}
  3. **Use deprecated @next-auth/* adapters** npm install @next-auth/prisma-adapter # ❌ Deprecated npm install @auth/prisma-adapter # ✅ Correct (v5)
  4. Use database session without edge-compatible adapter in middleware // WRONG - Prisma not edge-compatible export const {handlers, auth} = NextAuth({adapter: PrismaAdapter(prisma), session: {strategy: "database"}, // ❌ Fails in middleware})
  5. Mix v4 and v5 packages npm install next-auth@4.x @auth/core@0.x # ❌ Version mismatch

Common Errors & Fixes

1. Missing AUTH_SECRET

Error:

JWEDecryptionFailed: Invalid secret

Cause: Missing or incorrect AUTH_SECRET environment variable

Fix:

# Generate secret
npx auth secret

# Add to .env.local
AUTH_SECRET=your-generated-secret

# In production (Vercel, Cloudflare, etc.)
# Add AUTH_SECRET as environment variable in dashboard

2. CallbackRouteError

Error:

CallbackRouteError: Illegal arguments: string, undefined

Cause: Throwing errors in authorize() callback

Fix:

// WRONG
authorize: async (credentials) => {
  if (!user) throw new Error("Invalid credentials")
}

// CORRECT
authorize: async (credentials) => {
  if (!user) return null
  return user
}

3. Route Not Found

Error:

Error: next-auth route not found

Cause: Incorrect file path for API route handler

Fix:

// Ensure file is at EXACT path:
// app/api/auth/[...nextauth]/route.ts

import { handlers } from "@/auth"
export const { GET, POST } = handlers

4. Edge Compatibility Error

Error:

Module not compatible with edge runtime

Cause: Using non-edge adapter with database session strategy

Fix:

// Option 1: Force JWT sessions
export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" }, // ✅
})

// Option 2: Use edge-compatible adapter (D1)
export const { handlers, auth } = NextAuth({
  adapter: D1Adapter(env.DB), // ✅ Edge-compatible
  session: { strategy: "database" },
})

5. Session Not Updating

Error: Session expires but doesn't refresh

Cause: Missing middleware

Fix:

// middleware.ts
export { auth as middleware } from "@/auth"

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

6-12. More Errors

See references/common-errors.md for complete list of all 12 documented errors with fixes.


Templates Reference

All templates are available in the templates/ directory:

Next.js Templates (5)

  • auth.ts - Simple Next.js config (JWT sessions)
  • auth.config.ts + auth.ts - Split config (edge-compatible)
  • multi-provider.ts - OAuth + Credentials + Magic Links
  • middleware.ts - Session keep-alive + route protection
  • package.json +.env.example - Dependencies + environment

Cloudflare Workers Templates (3)

  • worker-hono-auth.ts - Complete Hono + Auth.js + D1
  • wrangler.jsonc - D1 binding configuration
  • schema.sql - D1 tables for Auth.js

Provider Templates (3)

  • oauth-github-google.ts - OAuth setup
  • credentials.ts - Email/password with Zod validation
  • magic-link-resend.ts - Passwordless email auth

Advanced Templates (2)

  • jwt-refresh-tokens.ts - Google token rotation example
  • role-based-access.ts - RBAC with custom claims

Copy these files to your project and customize as needed.


Package Versions

Current (as of 2025-10-26):

{
  "next-auth": "4.24.11",
  "@auth/core": "0.41.1",
  "@auth/d1-adapter": "1.11.1",
  "@auth/prisma-adapter": "2.7.5",
  "next": "15.3.1",
  "hono": "4.7.9"
}

Always use latest versions:

npm install next-auth@latest @auth/core@latest

Official Documentation


Reference Documentation

For deeper understanding, see:

  • common-errors.md - All 12 documented errors and fixes
  • edge-compatibility.md - Edge runtime compatibility matrix
  • v5-migration-guide.md - v4 → v5 breaking changes
  • session-strategies.md - JWT vs Database comparison
  • middleware-patterns.md - Route protection, RBAC
  • jwt-customization.md - Custom claims, token refresh
  • provider-setup-guides.md - OAuth app setup instructions

Questions? Issues?

  1. Check references/common-errors.md first
  2. Verify AUTH_SECRET is set
  3. Ensure you're not throwing in authorize()
  4. Check edge compatibility for your adapter
  5. Review official docs: https://authjs.dev

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

31.49%
按下载量换算78

windsurf

21.46%
按下载量换算53

OpenCode

15.93%
按下载量换算40

Codex

11.38%
按下载量换算28

Antigravity

8.53%
按下载量换算21

Gemini CLI

3.1%
按下载量换算8

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。

来源信息

继续浏览同类 Skills