Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

nextauth

/nextauth

Obsługuje uwierzytelnianie NextAuth.js w Next.js: dostawcy, sesje i callbacki, także z App Router.

Licencja
MIT
Ostatnia zmiana repozytorium
21.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
3
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 21.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Obsługuje uwierzytelnianie NextAuth.js w Next.js: dostawcy, sesje i callbacki, także z App Router.

Wyzwalacze z opisu

NextAuthNext.js authAuth.jsNext.js authenticationApp Router authnext-authauthentication providers
Oryginalny opis (EN)

NextAuth.js authentication for Next.js. Covers providers, sessions, and callbacks. Use for Next.js authentication. USE WHEN: user mentions "NextAuth", "Next.js auth", "Auth.js", asks about "Next.js authentication", "App Router auth", "next-auth", "authentication providers" DO NOT USE FOR: generic OAuth (use oauth2 skill), JWT implementation (use jwt skill), non-Next.js projects, Express/Fastify auth

Jak działa

  1. Basic Setup (App Router)
  2. Client Usage
  3. Server-Side Auth
  4. When NOT to Use This Skill
  5. Type Extensions
  6. Anti-Patterns
  7. Quick Troubleshooting
  8. Production Readiness
  9. Reference Documentation
Sekcje z nagłówków SKILL.md, w oryginale · 365 linii, 1 168 słów
Podgląd SKILL.md
---
name: nextauth
description: |
  NextAuth.js authentication for Next.js. Covers providers, sessions,
  and callbacks. Use for Next.js authentication.

  USE WHEN: user mentions "NextAuth", "Next.js auth", "Auth.js", asks about "Next.js authentication", "App Router auth", "next-auth", "authentication providers"

  DO NOT USE FOR: generic OAuth (use oauth2 skill), JWT implementation (use jwt skill), non-Next.js projects, Express/Fastify auth
allowed-tools: Read, Grep, Glob, Write, Edit
---
# NextAuth.js Core Knowledge

> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `nextauth` for comprehensive documentation.

## Basic Setup (App Router)

```typescript
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth';
import { authOptions } from '@/lib/auth';

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
```

```typescript
// lib/auth.ts
import { NextAuthOptions } from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import CredentialsProvider from 'next-auth/providers/credentials';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from './prisma';

export const authOptions: NextAuthOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    CredentialsProvider({
      name: 'credentials',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        const user = await prisma.user.findUnique({
          where: { email: credentials?.email },
        });
        if (user && await verifyPassword(credentials?.password, user.password)) {
          return user;
        }
        return null;
      },
    }),
  ],
  callbacks: {
    async session({ session, user }) {
      session.user.id = user.id;
      return session;
    },
  },
  pages: {
    signIn: '/login',
    error: '/auth/error',
  },
};
```

## Client Usage

```tsx
'use client';
import { useSession, signIn, signOut } from 'next-auth/react';

function AuthButton() {
  const { data: session, status } = useSession();

  if (status === 'loading') return <Spinner />;

  if (session) {
    return (
      <div>
        <span>{session.user?.email}</span>
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }

  return <button onClick={() => signIn('google')}>Sign in</button>;
}
```

## Server-Side Auth

```typescript
// In Server Component
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';

async function ProtectedPage() {
  const session = await getServerSession(authOptions);

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

  return <div>Welcome {session.user.name}</div>;
}
```

## When NOT to Use This Skill

- **Generic OAuth 2.0 flows** - Use `oauth2` skill for platform-agnostic OAuth
- **Custom JWT implementation** - Use `jwt` skill for custom token logic
- **Non-Next.js frameworks** - Use framework-specific auth (Express Passport, etc.)
- **Remix/SvelteKit** - Use their native auth solutions

## Type Extensions

```typescript
// types/next-auth.d.ts
declare module 'next-auth' {
  interface Session {
    user: { id: string; role: string } & DefaultSession['user'];
  }
}
```

## Anti-Patterns

| Anti-Pattern | Why It's Bad | Correct Approach |
|--------------|--------------|------------------|
| No NEXTAUTH_SECRET | Security vulnerability | Always set in production |
| Client-side session checks only | Can be bypassed | Use getServerSession() |
| Hardcoded provider credentials | Security risk | Use environment variables |
| No error handling | Poor UX | Implement custom error pages |
| Mixing session strategies | Inconsistent behavior | Stick to JWT or database |
| No CSRF protection | Vulnerable to attacks | Use default CSRF (enabled by default) |

## Quick Troubleshooting

| Issue | Cause | Solution |
|-------|-------|----------|
| "Configuration error" | Missing required env vars | Check NEXTAUTH_URL and NEXTAUTH_SECRET |
| Session is null | Not authenticated or session expired | Check signIn() was called |
| "Callback URL error" | Invalid redirect | Whitelist URLs in provider settings |
| Type errors | Missing type extensions | Create types/next-auth.d.ts |
| Session not updating | Cache issue | Call update() from useSession |
| CORS errors | Wrong domain | Ensure NEXTAUTH_URL matches deployment URL |

## Production Readiness

### Security Configuration

```typescript
// lib/auth.ts
import { NextAuthOptions } from 'next-auth';

export const authOptions: NextAuthOptions = {
  // Secure session configuration
  session: {
    strategy: 'jwt',
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },

  // Secure cookies
  cookies: {
    sessionToken: {
      name: process.env.NODE_ENV === 'production'
        ? '__Secure-next-auth.session-token'
        : 'next-auth.session-token',
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production',
      },
    },
  },

  // Callbacks for security
  callbacks: {
    async jwt({ token, user, account }) {
      if (user) {
        token.id = user.id;
        token.role = user.role;
      }
      return token;
    },
    async session({ session, token }) {
      session.user.id = token.id as string;
      session.user.role = token.role as string;
      return session;
    },
    async signIn({ user, account, profile }) {
      // Block suspicious sign-ins
      const isAllowed = await checkUserAllowed(user.email);
      return isAllowed;
    },
  },

  // Security events
  events: {
    async signIn({ user, account }) {
      await logSecurityEvent('signin', { userId: user.id, provider: account?.provider });
    },
    async signOut({ token }) {
      await logSecurityEvent('signout', { userId: token.sub });
    },
  },
};
```

### Rate Limiting

```typescript
// middleware.ts
import { NextResponse } from 'next/server';
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(5, '1 m'), // 5 requests per minute
});

export async function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/api/auth')) {
    const ip = request.ip ?? '127.0.0.1';
    const { success, limit, reset, remaining } = await ratelimit.limit(ip);

    if (!success) {
      return new NextResponse('Too Many Requests', {
        status: 429,
        headers: {
          'X-RateLimit-Limit': limit.toString(),
          'X-RateLimit-Remaining': remaining.toString(),
          'X-RateLimit-Reset': reset.toString(),
        },
      });
    }
  }

  return NextResponse.next();
}
```

### CSRF Protection

```typescript
// lib/auth.ts
export const authOptions: NextAuthOptions = {
  // Enable CSRF token verification
  useSecureCookies: process.env.NODE_ENV === 'production',

  // Custom CSRF token
  callbacks: {
    async redirect({ url, baseUrl }) {
      // Only allow redirects to same origin
      if (url.startsWith('/')) return `${baseUrl}${url}`;
      if (new URL(url).origin === baseUrl) return url;
      return baseUrl;
    },
  },
};

// In API routes, verify CSRF
import { getToken } from 'next-auth/jwt';

export async function POST(request: Request) {
  const token = await getToken({ req: request });
  if (!token) {
    return new Response('Unauthorized', { status: 401 });
  }
  // Process request
}
```

### Error Handling

```tsx
// app/auth/error/page.tsx
'use client';

import { useSearchParams } from 'next/navigation';

const errorMessages: Record<string, string> = {
  Configuration: 'Server configuration error',
  AccessDenied: 'Access denied',
  Verification: 'Verification link expired',
  Default: 'Authentication error',
};

export default function AuthError() {
  const searchParams = useSearchParams();
  const error = searchParams.get('error') ?? 'Default';

  return (
    <div className="error-page">
      <h1>Authentication Error</h1>
      <p>{errorMessages[error] ?? errorMessages.Default}</p>
      <a href="/login">Try again</a>
    </div>
  );
}
```

### Testing

```typescript
// __tests__/auth.test.ts
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';

// Mock next-auth
jest.mock('next-auth', () => ({
  getServerSession: jest.fn(),
}));

describe('Protected Route', () => {
  it('redirects unauthenticated users', async () => {
    (getServerSession as jest.Mock).mockResolvedValue(null);

    const response = await fetch('/api/protected');
    expect(response.status).toBe(401);
  });

  it('allows authenticated users', async () => {
    (getServerSession as jest.Mock).mockResolvedValue({
      user: { id: '1', email: 'test@example.com', role: 'user' },
    });

    const response = await fetch('/api/protected');
    expect(response.status).toBe(200);
  });
});

// E2E with Playwright
test('OAuth flow', async ({ page }) => {
  await page.goto('/login');
  await page.click('button:has-text("Sign in with Google")');

  // Mock OAuth provider response in test environment
  await expect(page).toHaveURL('/dashboard');
});
```

### Monitoring Metrics

| Metric | Target |
|--------|--------|
| Login success rate | > 99% |
| Auth latency | < 200ms |
| Failed login attempts | Monitor & alert |
| Token refresh success | > 99.9% |

### Checklist

- [ ] Secure cookie configuration
- [ ] JWT with appropriate maxAge
- [ ] Rate limiting on auth endpoints
- [ ] CSRF protection enabled
- [ ] Redirect URL validation
- [ ] Security event logging
- [ ] Custom error pages
- [ ] Session refresh strategy
- [ ] Role-based access control
- [ ] Testing with mocked sessions

## Reference Documentation
- [Providers](quick-ref/providers.md)
- [Callbacks](quick-ref/callbacks.md)
Pliki w paczce (3)
  • SKILL.md 10 KB
  • quick-ref/callbacks.md 6 KB
  • quick-ref/setup.md 5 KB

Wersje

RepozytoriumWynikLicencja
Ta strona · claude-dev-suite/claude-dev-suite100MIT
G1Joshi/Agent-Skills100MIT

Migawka bazy z 28.10.2026 · wersja paczki ed438847593d (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100auth-patterns
    Pomaga wdrażać uwierzytelnianie i autoryzację w aplikacjach Next.js: NextAuth, Auth.js, middleware, chronione trasy, zarządzanie sesjami, JWT i przepływ logowania.
  • 100nextjs-authentication
    Dostarcza wzorce uwierzytelniania dla Next.js 15+ App Router z Auth.js 5: przepływy logowania, chronione trasy, sesje, dostawcy OAuth i kontrola dostępu oparta na rolach.
  • 100oauth2
    Opisuje framework autoryzacji OAuth 2.0: przepływy, tokeny i integrację z dostawcami, przy logowaniu przez Google i GitHub oraz uwierzytelnianiu zewnętrznym.
  • 100agent-auth-specialist
    Wspiera uwierzytelnianie i autoryzację: OAuth 2.0 i OIDC, JWT, sesje, MFA, SSO oraz NextAuth, Clerk i Supabase Auth.
  • 100jwt
    Opisuje użycie JSON Web Tokens do bezpaństwowego uwierzytelniania: budowę tokenu, podpisywanie i walidację.
  • 100better-auth
    Pomaga skonfigurować Better Auth w TypeScript: instancję auth, adaptery, handlery tras, sesje i ciasteczka, wtyczki oraz migrację z NextAuth, Clerk, Auth0 lub Supabase Auth.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.