Skip to main content

authjs-skills

Auth.js v5 setup for Next.js authentication including Google OAuth, credentials provider, environment configuration, and core API integration

Ir a la instalación

Datos de origen

Repositorio
gocallum/nextjs16-agent-skills
Última actividad en el origen
19 de enero de 2026 a las 10:17
Idioma detectado de SKILL.md
inglés
Estrellas
23
Forks
7

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
authjs-skills
description
Auth.js v5 setup for Next.js authentication including Google OAuth, credentials provider, environment configuration, and core API integration
## Links - Getting Started: https://authjs.dev/getting-started/installation?framework=Next.js - Migrating to v5: https://authjs.dev/getting-started/migrating-to-v5 - Google Provider: https://authjs.dev/getting-started/providers/google - Credentials Provider: https://authjs.dev/getting-started/providers/credentials - Core API Reference: https://authjs.dev/reference/core - Session Management: https://authjs.dev/getting-started/session-management - Concepts: https://authjs.dev/concepts ## Installation ```sh pnpm add next-auth@beta ``` **Note**: Auth.js v5 is currently in beta. Use `next-auth@beta` to install the latest v5 version. ## What's New in Auth.js v5? ### Key Changes from v4 - **Simplified Configuration**: More streamlined setup with better TypeScript support - **Universal `auth()` Export**: Single function for authentication across all contexts - **Enhanced Security**: Improved CSRF protection and session handling - **Edge Runtime Support**: Full compatibility with Edge Runtime and middleware - **Better Type Safety**: Improved TypeScript definitions throughout ## Environment Variables ### Required Environment Variables ```env # Auth.js Configuration AUTH_SECRET=your_secret_key_here # Google OAuth (if using Google provider) AUTH_GOOGLE_ID=your_google_client_id AUTH_GOOGLE_SECRET=your_google_client_secret # For production deployments AUTH_URL=https://yourdomain.com # For development (optional, defaults to http://localhost:3000) # AUTH_URL=http://localhost:3000 ``` ### Generating AUTH_SECRET ```sh # Generate a random secret (Unix/Linux/macOS) openssl rand -base64 32 # Alternative using Node.js node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" # Using pnpm pnpm dlx auth secret ``` **Important**: Never commit `AUTH_SECRET` to version control. Use `.env.local` for development. ## Basic Setup (Next.js App Router) ### 1. Create `auth.ts` Configuration File Create `auth.ts` at the project root (next to `package.json`): ```typescript import NextAuth from "next-auth" import Google from "next-auth/providers/google" import Credentials from "next-auth/providers/credentials" export const { handlers, signIn, signOut, auth } = NextAuth({ providers: [ Google({ clientId: process.env.AUTH_GOOGLE_ID, clientSecret: process.env.AUTH_GOOGLE_SECRET, }), Credentials({ credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, }, authorize: async (credentials) => { // TODO: Implement your authentication logic here // This is a basic example - see Credentials Provider section below for complete implementation if (!credentials?.email || !credentials?.password) { return null } // Example: validate against database (placeholder) // See "Credentials Provider" section for full implementation with bcrypt const user = { id: "1", email: credentials.email, name: "User" } // Replace with actual DB lookup if (!user) { return null } return { id: user.id, email: user.email, name: user.name, } }, }), ], pages: { signIn: '/auth/signin', }, callbacks: { authorized: async ({ auth }) => { // Return true if user is authenticated return !!auth }, }, }) ``` **Note**: This is a basic setup example. For production-ready credentials authentication, see the "Credentials Provider" section below which includes proper password hashing with bcrypt and database integration. ### 2. Create API Route Handler Create `app/api/auth/[...nextauth]/route.ts`: ```typescript import { handlers } from "@/auth" export const { GET, POST } = handlers ``` ### 3. Add Middleware (Optional but Recommended) Create `middleware.ts` at the project root: ```typescript export { auth as middleware } from "@/auth" export const config = { matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], } ``` For more control: ```typescript import { auth } from "@/auth" export default auth((req) => { const isLoggedIn = !!req.auth const isOnDashboard = req.nextUrl.pathname.startsWith('/dashboard') if (isOnDashboard && !isLoggedIn) { return Response.redirect(new URL('/auth/signin', req.url)) } }) export const config = { matcher: ['/dashboard/:path*', '/profile/:path*'], } ``` ## Google OAuth Provider ### 1. Google Cloud Console Setup 1. Go to [Google Cloud Console](https://console.cloud.google.com/) 2. Create a new project or select existing 3. Enable Google+ API 4. Create OAuth 2.0 credentials: - Application type: Web application - Authorized redirect URIs: - Development: `http://localhost:3000/api/auth/callback/google` - Production: `https://yourdomain.com/api/auth/callback/google` 5. Copy Client ID and Client Secret to `.env.local` ### 2. Configuration ```typescript import NextAuth from "next-auth" import Google from "next-auth/providers/google" export const { handlers, signIn, signOut, 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" } } }), ], }) ``` ### 3. Google Provider Options ```typescript Google({ clientId: process.env.AUTH_GOOGLE_ID, clientSecret: process.env.AUTH_GOOGLE_SECRET, // Request additional scopes authorization: { params: { scope: "openid email profile", prompt: "select_account", // Force account selection } }, // Allow specific domains only allowDangerousEmailAccountLinking: false, }) ``` ## Credentials Provider (Username/Password) ### Required Dependencies ```sh # Install required packages for credentials provider pnpm add bcryptjs zod pnpm add -D @types/bcryptjs ``` ### 1. Basic Configuration ```typescript import NextAuth from "next-auth" import Credentials from "next-auth/providers/credentials" import { z } from "zod" import bcrypt from "bcryptjs" import { prisma } from "@/lib/prisma" const credentialsSchema = z.object({ email: z.string().email(), password: z.string().min(8), }) export const { handlers, signIn, signOut, auth } = NextAuth({ providers: [ Credentials({ credentials: { email: { label: "Email", type: "email", placeholder: "user@example.com" }, password: { label: "Password", type: "password" }, }, authorize: async (credentials) => { try { const { email, password } = credentialsSchema.parse(credentials) // Fetch user from database const user = await prisma.user.findUnique({ where: { email }, }) if (!user) { throw new Error("User not found") } // Verify password const isValidPassword = await bcrypt.compare(password, user.hashedPassword) if (!isValidPassword) { throw new Error("Invalid password") } // Return user object (must include id) return { id: user.id, email: user.email, name: user.name, image: user.image, } } catch (error) { console.error("Authentication error:", error) return null } }, }), ], session: { strategy: "jwt", // Required for credentials provider }, }) ``` ### 2. User Registration Example ```typescript // app/api/auth/register/route.ts import { NextResponse } from "next/server" import bcrypt from "bcryptjs" import { z } from "zod" import { prisma } from "@/lib/prisma" const registerSchema = z.object({ email: z.string().email(), password: z.string().min(8), name: z.string().min(2), }) export async function POST(req: Request) { try { const body = await req.json() const { email, password, name } = registerSchema.parse(body) // Check if user exists const existingUser = await prisma.user.findUnique({ where: { email }, }) if (existingUser) { return NextResponse.json( { error: "User already exists" }, { status: 400 } ) } // Hash password const hashedPassword = await bcrypt.hash(password, 10) // Create user const user = await prisma.user.create({ data: { email, name, hashedPassword, }, }) return NextResponse.json( { message: "User created successfully", userId: user.id }, { status: 201 } ) } catch (error) { console.error("Registration error:", error) return NextResponse.json( { error: "Failed to register user" }, { status: 500 } ) } } ``` ## Using Auth in Components ### Server Components ```typescript import { auth } from "@/auth" export default async function ProfilePage() { const session = await auth() if (!session?.user) { return <div>Not authenticated</div> } return ( <div> <h1>Welcome, {session.user.name}!</h1> <p>Email: {session.user.email}</p> </div> ) } ``` ### Server Actions ```typescript "use server" import { auth } from "@/auth" import { revalidatePath } from "next/cache" import { prisma } from "@/lib/prisma" export async function updateProfile(formData: FormData) { const session = await auth() if (!session?.user) { throw new Error("Not authenticated") } const name = formData.get("name") as string // Update database await prisma.user.update({ where: { id: session.user.id }, data: { name }, }) revalidatePath("/profile") } ``` ### Client Components (with SessionProvider) ```typescript // app/providers.tsx "use client" import { SessionProvider } from "next-auth/react" export function Providers({ children }: { children: React.ReactNode }) { return <SessionProvider>{children}</SessionProvider> } ``` ```typescript // app/layout.tsx import { Providers } from "./providers" export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <Providers>{children}</Providers> </body> </html> ) } ``` ```typescript // app/components/user-profile.tsx "use client" import { useSession, signIn, signOut } from "next-auth/react" export function UserProfile() { const { data: session, status } = useSession() if (status === "loading") { return <div>Loading...</div> } if (!session) { return ( <button onClick={() => signIn()}> Sign In </button> ) } return ( <div> <p>Signed in as {session.user?.email}</p> <button onClick={() => signOut()}> Sign Out </button> </div> ) } ``` ## Sign In/Out Actions ### Programmatic Sign In ```typescript import { signIn } from "@/auth" // Server Action export async function handleSignIn(provider: string) { "use server" await signIn(provider) }
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub