Auth.js v5 στο Next.js 15: Πλήρης Οδηγός Authentication με OAuth, Credentials και Middleware
Πλήρης οδηγός για Auth.js v5 στο Next.js 15 App Router: OAuth, Credentials, JWT vs database sessions, middleware και Drizzle adapter με έτοιμα παραδείγματα.
Το Auth.js v5 (η νέα έκδοση του NextAuth.js) είναι μια ολοκληρωμένη βιβλιοθήκη authentication για το Next.js 15 App Router, που υποστηρίζει OAuth providers, credentials, magic links και passkeys κάτω από ενιαία API. Στην έκδοση 5, η αρχιτεκτονική προσαρμόστηκε πλήρως στα React Server Components και τα Server Actions: η συνάρτηση auth() αντικαθιστά το getServerSession, η ρύθμιση γίνεται από ένα κεντρικό αρχείο auth.ts, και το middleware integration είναι first-class. Σε αυτόν τον οδηγό θα δούμε βήμα-βήμα πώς στήνεται.
Honestly, η διαφορά εμπειρίας από το v4 είναι τεράστια. Στο τελευταίο μου project μετέφερα μια εφαρμογή SaaS από NextAuth v4 σε Auth.js v5 και ο κώδικας authentication μειώθηκε σχεδόν στο μισό.
Το Auth.js v5 (beta από το 2024, σταθερό το 2025/2026) είναι ο διάδοχος του NextAuth.js με Universal API και πλήρη υποστήριξη Edge runtime.
Το setup γίνεται σε ένα αρχείο auth.ts που εξάγει τις { handlers, auth, signIn, signOut }, αντικαθιστώντας το παλιό [...nextauth]/route.ts pattern.
Η συνάρτηση auth() δουλεύει σε Server Components, Route Handlers, Server Actions και Middleware χωρίς ξεχωριστά helpers.
Με database adapters (Drizzle, Prisma, MongoDB) μπορείς να αποθηκεύεις χρήστες και sessions στη βάση δεδομένων, αλλιώς χρησιμοποιείται JWT.
Το middleware integration με NextAuth({...}).auth ως default export προστατεύει routes χωρίς manual cookie parsing.
Τι είναι το Auth.js v5 και τι αλλάζει από το NextAuth;
Το Auth.js είναι το επίσημο rebrand του NextAuth.js, που σηματοδοτεί τη μετατροπή της βιβλιοθήκης σε framework-agnostic authentication layer. Παρότι το πακέτο συνεχίζει να δημοσιεύεται ως next-auth για το Next.js, υπάρχουν πλέον και adapters για SvelteKit (@auth/sveltekit), Express (@auth/express) και Qwik. Στην πράξη, για το Next.js η εμπειρία ανάπτυξης αλλάζει δραστικά σε σχέση με το v4.
Οι σημαντικότερες αλλαγές που πρέπει να γνωρίζεις πριν ξεκινήσεις:
Ενιαίο αρχείο auth.ts: Αντί για ξεχωριστή ρύθμιση σε [...nextauth]/route.ts και imports σε κάθε file, καλείς μία φορά τη NextAuth(config) και εξάγεις τα handlers μαζί με helpers.
Universal auth() function: Αντικαθιστά τα getServerSession, getSession, withAuth. Δουλεύει παντού: Server Components, Route Handlers, Middleware, Server Actions.
Edge-compatible πλέον by default: Με κατάλληλο διαχωρισμό config (Edge-safe παράγοντες χωρίς Node modules) τρέχει σε Edge runtime.
Account linking: Νέο API allowDangerousEmailAccountLinking και βελτιωμένο linking flow για πολλαπλούς providers.
Καλύτερο TypeScript: Τα callbacks έχουν πλέον σωστά τυποποιημένα user, token και session objects.
Εγκατάσταση και αρχικό setup σε Next.js 15
So, ας ξεκινήσουμε. Για ένα Next.js 15 project με App Router, εγκατέστησε το πακέτο και δημιούργησε ένα κρυπτογραφικά ισχυρό AUTH_SECRET:
pnpm add next-auth@beta
# δημιούργησε secret για JWT signing
npx auth secret
# προσθέτει AUTH_SECRET στο .env.local αυτόματα
Στη συνέχεια δημιούργησε ένα αρχείο auth.ts στη ρίζα του project (όχι μέσα στο app/):
// auth.ts
import NextAuth from "next-auth"
import GitHub from "next-auth/providers/github"
import Google from "next-auth/providers/google"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [GitHub, Google],
pages: {
signIn: "/login",
},
callbacks: {
authorized: async ({ auth }) => {
// αν επιστρέψει true ο χρήστης έχει access
return !!auth
},
},
})
Το catch-all route handler συνδέει το Auth.js με τα Next.js Route Handlers:
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth"
export const { GET, POST } = handlers
Με μόλις αυτά τα τρία αρχεία, το Auth.js είναι λειτουργικό. Τα endpoints /api/auth/signin, /api/auth/signout, /api/auth/session και /api/auth/callback/[provider] είναι έτοιμα.
Σύνδεση με OAuth providers (Google, GitHub)
Το Auth.js v5 υποστηρίζει πάνω από 80 OAuth providers out-of-the-box. Για το GitHub θα χρειαστείς ένα OAuth App από το GitHub Developer Settings, με callback URL http://localhost:3000/api/auth/callback/github. Για το Google αντίστοιχα από το Google Cloud Console.
Το Auth.js αναγνωρίζει αυτόματα τις μεταβλητές με πρόθεμα AUTH_, οπότε δεν χρειάζεται manual configuration. Σε ένα Server Component μπορείς πλέον να ελέγξεις την session του χρήστη απευθείας:
Πρόσεξε ότι οι κλήσεις signIn και signOut γίνονται μέσω inline Server Actions. Αυτό είναι το επίσημο pattern σε App Router και δεν χρειάζεται client component. Για περισσότερα patterns με μεταβολές δεδομένων δες τον οδηγό μας για Server Actions στο Next.js 15.
Credentials provider με email και password
Αν θες παραδοσιακό email/password login, ο Credentials provider σου επιτρέπει να ορίσεις δική σου authorize function. Σε αντίθεση με τους OAuth providers, εδώ είσαι 100% υπεύθυνος για password hashing, rate limiting και validation.
Το Auth.js υποστηρίζει δύο στρατηγικές session: JWT (stateless, default) και database (stateful). Η επιλογή επηρεάζει σημαντικά απόδοση και λειτουργικότητα.
Χαρακτηριστικό
JWT Strategy
Database Strategy
Αποθήκευση
Encrypted cookie (JWE)
Row σε sessions table
Edge runtime
Πλήρως συμβατό
Απαιτεί DB connection
Immediate revoke
Μέχρι expiration
Διαγραφή row
Scaling
Stateless (εύκολο)
Χρειάζεται sticky DB
Default expiration
30 ημέρες
30 ημέρες (configurable)
Credentials provider
Υποχρεωτικό
Δεν υποστηρίζεται
Custom data στο session
Μέσω jwt callback
Μέσω session callback
Για τις περισσότερες εφαρμογές προτείνουμε JWT strategy. Λειτουργεί παντού, scales οριζόντια και έχει χαμηλότερο latency. Πρόσθεσε custom claims στο token μέσω callbacks:
callbacks: {
jwt: async ({ token, user }) => {
if (user) {
token.id = user.id
token.role = user.role
}
return token
},
session: async ({ session, token }) => {
if (session.user) {
session.user.id = token.id as string
session.user.role = token.role as string
}
return session
},
},
Για επέκταση των TypeScript types, δημιούργησε ένα next-auth.d.ts με module augmentation:
Το middleware integration του Auth.js v5 είναι από τις πιο καθαρές αλλαγές σε σχέση με το v4. Αντί για το παλιό withAuth HOC, εξάγεις απευθείας την auth ως default export:
// middleware.ts
export { auth as middleware } from "@/auth"
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}
Αυτό τρέχει τον authorized callback που ορίσαμε στο auth.ts πριν από κάθε request. Για πιο fine-grained logic, μπορείς να γράψεις custom middleware function:
import { DrizzleAdapter } from "@auth/drizzle-adapter"
import { db } from "@/db"
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: DrizzleAdapter(db),
providers: [GitHub, Google],
session: { strategy: "jwt" }, // ή "database"
})
Για περισσότερα για το Drizzle setup, schema migrations και relations, δες τον αναλυτικό μας οδηγό για Drizzle ORM στο Next.js App Router.
Sign-in και sign-out με Server Actions
Σε προηγούμενες εκδόσεις του NextAuth, το client-side signIn() από το next-auth/react ήταν το standard pattern. Στο Auth.js v5 με App Router, οι Server Actions προσφέρουν πιο καθαρή, type-safe και progressively-enhanced εμπειρία.
// app/login/page.tsx
import { signIn } from "@/auth"
import { AuthError } from "next-auth"
import { redirect } from "next/navigation"
async function login(formData: FormData) {
"use server"
try {
await signIn("credentials", {
email: formData.get("email"),
password: formData.get("password"),
redirectTo: "/dashboard",
})
} catch (error) {
if (error instanceof AuthError) {
switch (error.type) {
case "CredentialsSignin":
return redirect("/login?error=invalid")
default:
return redirect("/login?error=unknown")
}
}
throw error // Next.js redirect throws, οπότε πρέπει να ξανα-throw
}
}
export default function LoginPage() {
return (
<form action={login}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit">Sign in</button>
</form>
)
}
Συνηθισμένα προβλήματα και αντιμετώπιση
Παρακάτω τα πιο συχνά λάθη που βλέπουμε στα Auth.js v5 setups, και πώς να τα αποφύγεις.
Σφάλμα: "MissingSecret"
Δεν έχει οριστεί η AUTH_SECRET environment variable. Τρέξε npx auth secret για αυτόματη γέννηση, ή δημιούργησε χειροκίνητα με openssl rand -base64 32. Σε production (Vercel, Cloudflare), πρόσθεσε το secret στις environment variables του project.
Σφάλμα: "Edge runtime does not support Node.js 'crypto' module"
Συμβαίνει όταν εισάγεις bcrypt, Prisma client ή Node-only βιβλιοθήκη στο middleware. Διαχώρισε το config: φτιάξε auth.config.ts με μόνο OAuth providers (Edge-safe) και χρησιμοποίησέ το στο middleware. Το full auth.ts με Credentials + adapter παραμένει για το API route.
Το session επιστρέφει null αμέσως μετά το signIn
Σχεδόν πάντα είναι θέμα cookie configuration. Έλεγξε ότι το AUTH_URL ταιριάζει με το πραγματικό domain (συμπεριλαμβανομένου https:// σε production) και ότι δεν έχεις SameSite=Strict cookies σε cross-origin OAuth callbacks.
OAuth callback redirect loop
Συνήθως είναι λάθος callback URL στο developer console του provider. Το pattern είναι {AUTH_URL}/api/auth/callback/{provider}. Για localhost χρησιμοποίησε http://localhost:3000/api/auth/callback/github ακριβώς όπως είναι στο GitHub OAuth App settings.
Συχνές ερωτήσεις
Είναι το Auth.js το ίδιο με το NextAuth.js;
Το Auth.js είναι το rebranded όνομα του project NextAuth.js και πλέον υποστηρίζει πολλά frameworks (Next.js, SvelteKit, Express, Qwik). Για το Next.js το πακέτο εξακολουθεί να ονομάζεται next-auth και η v5 είναι η σταθερή έκδοση που στοχεύει το App Router.
Μπορώ να χρησιμοποιήσω Auth.js v5 με το Pages Router;
Ναι, αλλά το v5 σχεδιάστηκε με προτεραιότητα το App Router. Για legacy projects σε Pages Router, το v4 (next-auth@4) παραμένει υποστηριζόμενο. Αν ξεκινάς νέο project το 2026, χρησιμοποίησε App Router μαζί με v5.
Πώς προσθέτω custom πεδία στο session του χρήστη;
Μέσω των jwt και session callbacks στο auth.ts: πρόσθεσε τα πεδία στο token στο πρώτο, και επανέφερέ τα στο session object στο δεύτερο. Επέκτεινε επίσης τους TypeScript τύπους με module augmentation σε ένα next-auth.d.ts αρχείο.
Υποστηρίζει το Auth.js v5 passkeys και WebAuthn;
Ναι. Υπάρχει επίσημος WebAuthn provider (@auth/webauthn-provider) που υλοποιεί passwordless authentication με passkeys. Απαιτεί database adapter για αποθήκευση των authenticator credentials και είναι σε σταθερή κατάσταση από τα τέλη του 2025.
Πώς κάνω logout τον χρήστη server-side;
Εισάγεις το signOut από το @/auth και το καλείς μέσα σε Server Action: await signOut({ redirectTo: "/" }). Αυτό διαγράφει το session cookie (JWT strategy) ή τη session row (database strategy) και κάνει redirect.
Πώς να διαχειριστείτε σφάλματα στο Next.js App Router με error.tsx, global-error.tsx, not-found.tsx και Server Actions. Οδηγός με useActionState, Sentry monitoring και πρακτικά παραδείγματα κώδικα.