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

nextjs-authentication

Provides authentication implementation patterns for Next.js 15+ App Router using Auth.js 5 (NextAuth.js). Use when setting up authentication flows, implementing protected routes, managing sessions in Server Components and Server Actions, configuring OAuth providers, implementing role-based access control, or handling sign-in/sign-out flows in Next.js applications.

インストール方法を見る

含まれるファイル(7)

  • SKILL.md11.0 KB
  • references/authjs-setup.md11.3 KB
  • references/best-practices.md2.2 KB
  • references/database-adapter.md12.6 KB
  • references/examples.md4.1 KB
  • references/oauth-providers.md9.7 KB
  • references/testing-patterns.md15.4 KB

SKILL.md(原文)

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

Next.js Authentication

Overview

Provides authentication implementation patterns for Next.js 15+ App Router using Auth.js 5 (NextAuth.js), covering the complete authentication lifecycle from initial setup to production-ready role-based access control implementations.

When to Use

  • Setting up Auth.js 5 from scratch or adding OAuth providers
  • Implementing protected routes with Middleware
  • Handling authentication in Server Components and Server Actions
  • Implementing role-based access control (RBAC)
  • Creating credential-based or OAuth sign-in/sign-out flows

Instructions

1. Install Dependencies

Install Auth.js v5 (beta) for Next.js App Router:

npm install next-auth@beta

2. Configure Environment Variables

Create .env.local with required variables:

# Required for Auth.js
AUTH_SECRET="your-secret-key-here"
AUTH_URL="http://localhost:3000"

# OAuth Providers (add as needed)
GITHUB_ID="your-github-client-id"
GITHUB_SECRET="your-github-client-secret"
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"

Generate AUTH_SECRET with:

openssl rand -base64 32

3. Create Auth Configuration

Create auth.ts in the project root with providers and callbacks:

import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";

export const {
  handlers: { GET, POST },
  auth,
  signIn,
  signOut,
} = NextAuth({
  providers: [
    GitHub({
      clientId: process.env.GITHUB_ID!,
      clientSecret: process.env.GITHUB_SECRET!,
    }),
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id;
      }
      return token;
    },
    async session({ session, token }) {
      if (token) {
        session.user.id = token.id as string;
      }
      return session;
    },
  },
  pages: {
    signIn: "/login",
    error: "/error",
  },
});

4. Create API Route Handler

Create app/api/auth/[...nextauth]/route.ts:

export { GET, POST } from "@/auth";

5. Add Middleware for Route Protection

Create middleware.ts in the project root:

import { auth } from "@/auth";
import { NextResponse } from "next/server";

export default auth((req) => {
  const { nextUrl } = req;
  const isLoggedIn = !!req.auth;
  const isApiAuthRoute = nextUrl.pathname.startsWith("/api/auth");
  const isPublicRoute = ["/", "/login", "/register"].includes(nextUrl.pathname);
  const isProtectedRoute = nextUrl.pathname.startsWith("/dashboard");

  if (isApiAuthRoute) return NextResponse.next();

  if (!isLoggedIn && isProtectedRoute) {
    return NextResponse.redirect(new URL("/login", nextUrl));
  }

  if (isLoggedIn && nextUrl.pathname === "/login") {
    return NextResponse.redirect(new URL("/dashboard", nextUrl));
  }

  return NextResponse.next();
});

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

6. Access Session in Server Components

Use the auth() function to access session in Server Components:

import { auth } from "@/auth";
import { redirect } from "next/navigation";

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

  if (!session) {
    redirect("/login");
  }

  return (
    <div>
      <h1>Welcome, {session.user.name}</h1>
    </div>
  );
}

7. Secure Server Actions

Always verify authentication in Server Actions before mutations:

"use server";

import { auth } from "@/auth";

export async function createTodo(formData: FormData) {
  const session = await auth();

  if (!session?.user) {
    throw new Error("Unauthorized");
  }

  // Proceed with protected action
  const title = formData.get("title") as string;
  await db.todo.create({
    data: { title, userId: session.user.id },
  });
}

8. Handle Sign-In/Sign-Out

Create a login page with server action:

// app/login/page.tsx
import { signIn } from "@/auth";
import { redirect } from "next/navigation";

export default function LoginPage() {
  async function handleLogin(formData: FormData) {
    "use server";

    const result = await signIn("credentials", {
      email: formData.get("email"),
      password: formData.get("password"),
      redirect: false,
    });

    if (result?.error) {
      return { error: "Invalid credentials" };
    }

    redirect("/dashboard");
  }

  return (
    <form action={handleLogin}>
      <input name="email" type="email" placeholder="Email" required />
      <input name="password" type="password" placeholder="Password" required />
      <button type="submit">Sign In</button>
    </form>
  );
}

For client-side sign-out:

"use client";

import { signOut } from "next-auth/react";

export function SignOutButton() {
  return <button onClick={() => signOut()}>Sign Out</button>;
}

9. Implement Role-Based Access

Check roles in Server Components:

import { auth } from "@/auth";
import { unauthorized } from "next/navigation";

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

  if (session?.user?.role !== "admin") {
    unauthorized();
  }

  return <AdminDashboard />;
}

10. Extend TypeScript Types

Create types/next-auth.d.ts for type-safe sessions:

import { DefaultSession } from "next-auth";

declare module "next-auth" {
  interface Session {
    user: {
      id: string;
      role: "user" | "admin";
    } & DefaultSession["user"];
  }

  interface User {
    role?: "user" | "admin";
  }
}

declare module "next-auth/jwt" {
  interface JWT {
    id?: string;
    role?: "user" | "admin";
  }
}

Examples

Example 1: Complete Protected Dashboard

Input: User needs a dashboard accessible only to authenticated users

Implementation:

// app/dashboard/page.tsx
import { auth } from "@/auth";
import { redirect } from "next/navigation";
import { getUserTodos } from "@/app/lib/data";

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

  if (!session?.user?.id) {
    redirect("/login");
  }

  const todos = await getUserTodos(session.user.id);

  return (
    <main>
      <h1>Welcome, {session.user.name}</h1>
      <p>Email: {session.user.email}</p>
      <TodoList todos={todos} />
    </main>
  );
}

Output: Dashboard renders only for authenticated users, with their specific data.

Example 2: Role-Based Admin Panel

Input: Admin panel should be accessible only to users with "admin" role

Implementation:

// app/admin/page.tsx
import { auth } from "@/auth";
import { unauthorized } from "next/navigation";

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

  if (session?.user?.role !== "admin") {
    unauthorized();
  }

  return (
    <main>
      <h1>Admin Panel</h1>
      <p>Welcome, administrator {session.user.name}</p>
    </main>
  );
}

Output: Only admin users see the panel; others get 401 error.

Example 3: Secure Server Action with Form

Input: Form submission should only work for authenticated users

Implementation:

// app/components/create-todo-form.tsx
"use server";

import { auth } from "@/auth";
import { revalidatePath } from "next/cache";

export async function createTodo(formData: FormData) {
  const session = await auth();

  if (!session?.user?.id) {
    throw new Error("Unauthorized");
  }

  const title = formData.get("title") as string;

  await db.todo.create({
    data: {
      title,
      userId: session.user.id,
    },
  });

  revalidatePath("/dashboard");
}

// Usage in component
export function CreateTodoForm() {
  return (
    <form action={createTodo}>
      <input name="title" placeholder="New todo..." required />
      <button type="submit">Add Todo</button>
    </form>
  );
}

Output: Todo created only for authenticated user; unauthorized requests throw error.

Best Practices

  1. Use Server Components by default - Access session directly without client-side JavaScript
  2. Minimize Client Components - Only use useSession() for reactive session updates
  3. Cache session checks - Use React's cache() for repeated lookups in the same render
  4. Middleware for optimistic checks - Redirect quickly, but always re-verify in Server Actions
  5. Treat Server Actions like API endpoints - Always authenticate before mutations
  6. Never hardcode secrets - Use environment variables for all credentials
  7. Implement proper error handling - Return appropriate HTTP status codes
  8. Use TypeScript type extensions - Extend NextAuth types for custom fields
  9. Separate auth logic - Create a DAL (Data Access Layer) for consistent checks
  10. Test authentication flows - Mock auth() function in unit tests

Constraints and Warnings

Critical Limitations

  • Middleware runs on Edge runtime - Cannot use Node.js APIs like database drivers
  • Server Components cannot set cookies - Use Server Actions for cookie operations
  • Session callback timing - Only called on session creation/access, not every request

Common Mistakes

// ❌ WRONG: Setting cookies in Server Component
export default async function Page() {
  cookies().set("key", "value"); // Won't work
}

// ✅ CORRECT: Use Server Action
async function setCookieAction() {
  "use server";
  cookies().set("key", "value");
}
// ❌ WRONG: Database queries in Middleware
export default auth(async (req) => {
  const user = await db.user.findUnique(); // Won't work in Edge
});

// ✅ CORRECT: Use only Edge-compatible APIs
export default auth(async (req) => {
  const session = req.auth; // This works
});

Security Considerations

  • Always verify authentication in Server Actions - middleware alone is not enough
  • Use unauthorized() for unauthenticated access, redirect() for other cases
  • Store sensitive tokens in httpOnly cookies
  • Validate all user input before processing
  • Use HTTPS in production
  • Set appropriate cookie sameSite attributes

References

レビュー

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

同じリポジトリのスキル

概要と使いどころ

Creates new Architecture Decision Record (ADR) documents for significant architectural changes using a consistent template and repository-aware naming and storage guidance. Use when a user or agent decides on an architectural change, needs to document technical rationale, or wants to add a new ADR to the project history.

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

aws-cdk

無料

Provides AWS CDK TypeScript patterns for defining, validating, and deploying AWS infrastructure as code. Use when creating CDK apps, stacks, and reusable constructs, modeling serverless or VPC-based architectures, applying IAM and encryption defaults, or testing and reviewing `cdk synth`, `cdk diff`, and `cdk deploy` changes. Triggers include "aws cdk typescript", "create cdk app", "cdk stack", "cdk construct", "cdk deploy", and "cdk test".

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

Provides advanced AWS CLI patterns for managing EC2, Lambda, S3, DynamoDB, RDS, VPC, IAM, and CloudWatch. Generates bulk operation scripts, automates cross-service workflows, validates security configurations, and executes JMESPath queries for complex filtering. Triggers on "aws cli help", "aws command line", "aws scripting", "aws automation", "aws batch operations", "aws bulk operations", "aws cli pagination", "aws multi-region", "aws profiles", "aws cli troubleshooting".

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

Provides AWS CloudFormation patterns for Auto Scaling including EC2, ECS, and Lambda. Use when creating Auto Scaling groups, launch configurations, launch templates, scaling policies, lifecycle hooks, and predictive scaling. Covers template structure with Parameters, Outputs, Mappings, Conditions, cross-stack references, and best practices for high availability and cost optimization.

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

Provides AWS CloudFormation patterns for Amazon Bedrock resources including agents, knowledge bases, data sources, guardrails, prompts, flows, and inference profiles. Use when creating Bedrock agents with action groups, implementing RAG with knowledge bases, configuring vector stores, setting up content moderation guardrails, managing prompts, orchestrating workflows with flows, and configuring inference profiles for model optimization.

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

Provides AWS CloudFormation patterns for CloudFront distributions, origins (ALB, S3, Lambda@Edge, VPC Origins), CacheBehaviors, Functions, SecurityHeaders, parameters, Outputs and cross-stack references. Use when creating CloudFront distributions with CloudFormation, configuring multiple origins, implementing caching strategies, managing custom domains with ACM, configuring WAF, and optimizing performance.

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

giuseppe-trisciuoglio/developer-kit3572026年9月10日 更新

giuseppe-trisciuoglio のスキルをすべて見る

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