1. Почему вообще есть две функции: auth() и getServerSession()?
В Next.js 13+ (и особенно в App Router, который используется в Next.js 15) появились новые подходы к серверному и клиентскому коду, а вместе с ними — новые способы работы с сессиями.
- auth() — это современный, "нативный" способ получения данных о сессии пользователя внутри Server Components и Server Actions. Он предоставляется пакетом @auth/nextjs (или next-auth в старых версиях).
- getServerSession() — это более универсальная функция, которая появилась раньше и поддерживается в классическом Page Router, API Routes, а также в серверном коде вне компонентов Next.js.
На первый взгляд, обе функции делают примерно одно и то же: возвращают объект сессии (или null), если пользователь не авторизован. Но есть нюансы, которые важно понимать, чтобы избежать багов и головной боли.
auth(): когда и как использовать
Функция auth() — это современный способ получения сессии в App Router (папка app/). Она максимально проста в использовании:
// app/layout.tsx или app/page.tsx
import { auth } from "@auth/nextjs";
export default async function Layout({ children }) {
const session = await auth();
return (
<html>
<body>
{session?.user ? (
<p>Привет, {session.user.name}!</p>
) : (
<p>Вы не авторизованы</p>
)}
{children}
</body>
</html>
);
}
- Работает только на сервере (Server Components, Server Actions).
- Всё просто: не нужно передавать параметры, не нужно думать о контексте — next-auth сам разберётся, где вы находитесь.
- Синтаксис максимально лаконичный: просто const session = await auth();
Где auth() не работает
- В Page Router (pages/), в классических API Routes.
- В клиентских компонентах (Client Components).
- В middleware (там есть отдельная функция — getToken()).
2. getServerSession(): универсальность и гибкость
Функция getServerSession() — это старый, но проверенный способ получить сессию пользователя на сервере. Она поддерживается везде, где есть доступ к объектам запроса и ответа (req, res):
- В API Routes (pages/api/)
- В классических getServerSideProps, getInitialProps
- В кастомных серверных обработчиках (например, в Express или Fastify)
- В некоторых случаях — даже в App Router, если нужно больше контроля
Пример использования:
// pages/api/profile.js
import { getServerSession } from "next-auth";
import { authOptions } from "../../authOptions";
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
res.status(401).json({ error: "Не авторизован" });
return;
}
res.status(200).json({ user: session.user });
}
- Вы явно передаёте req, res и объект настроек авторизации (authOptions).
- Вы можете использовать функцию в любом месте, где есть доступ к этим объектам.
Где getServerSession() не нужен
- В App Router, если вы работаете только с Server Components — используйте auth().
- В Client Components — ни одна из этих функций не работает (используйте useSession()).
3. Сравнение: auth() vs getServerSession()
| Характеристика | auth() (App Router) | getServerSession() (универсально) |
|---|---|---|
| Где применяется | Server Components, Server Actions, app/ | API Routes, getServerSideProps, кастомные серверы, иногда app/ |
| Аргументы | Не требует аргументов | Требует req, res, authOptions |
| Простота использования | Максимальная | Нужно больше кода |
| Совместимость с App Router | Да | Да, но не всегда удобно |
| Совместимость с Page Router | Нет | Да |
| Работа с клиентом | Нет | Нет |
Вывод:
Если вы пишете современное Next.js-приложение на App Router — используйте auth().
Если вы пишете API Route или SSR-страницу — используйте getServerSession().
4. Пример совместимости и перехода
Представим, что у вас есть проект, где часть логики работает через API Routes (например, /api/profile), а часть через новые Server Components (app/profile/page.tsx). Как быть с сессией?
- В API Route используйте getServerSession(req, res, authOptions).
- В Server Component используйте auth().
// app/profile/page.tsx
import { auth } from "@auth/nextjs";
export default async function ProfilePage() {
const session = await auth();
// ... используем session
}
// pages/api/profile.js
import { getServerSession } from "next-auth";
import { authOptions } from "../../authOptions";
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
// ... используем session
}
Таким образом, обе функции могут спокойно сосуществовать в одном проекте, и вы выбираете подходящий инструмент под конкретную задачу.
5. Совместимость, backward compatibility и "подводные камни"
Что будет, если перепутать функции?
Если попытаться вызвать auth() в Page Router или API Route, вы получите ошибку: "auth() can only be used in Server Components or Server Actions".
Если наоборот, вызвать getServerSession() в Server Component без req и res, будет ошибка или не будет работать как ожидается.
Совместимость настроек
Обе функции используют одни и те же настройки (authOptions). Обычно их выносит в отдельный файл (authOptions.js или auth.config.js), чтобы не дублировать код.
// authOptions.js
export const authOptions = {
providers: [
// ... ваши провайдеры
],
// другие настройки
};
- В API Route: импортируете и передаёте в getServerSession.
- В App Router: next-auth сам подхватит эти настройки (или вы явно указываете путь к ним).
Совместимость между версиями next-auth
- В старых проектах (Next.js 12 и ниже, Page Router) используется только getServerSession().
- В новых проектах (Next.js 13+, App Router) — auth().
- Если вы обновляете проект, можно постепенно переписывать логику авторизации, используя обе функции параллельно.
6. Практика: интеграция обеих функций в одном проекте
Давайте рассмотрим небольшой пример приложения "Заметки", где:
- Список заметок отображается на защищённой странице (/notes) через Server Component (используем auth()).
- Добавление новой заметки идёт через API Route (/api/notes), где мы проверяем сессию через getServerSession().
/app/notes/page.tsx
import { auth } from "@auth/nextjs";
export default async function NotesPage() {
const session = await auth();
if (!session) {
return <p>Пожалуйста, войдите в систему</p>;
}
// Получаем заметки пользователя...
return <NotesList userId={session.user.id} />;
}
/pages/api/notes.js
import { getServerSession } from "next-auth";
import { authOptions } from "../../authOptions";
export default async function handler(req, res) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
res.status(401).json({ error: "Не авторизован" });
return;
}
// Добавляем новую заметку для session.user.id
// ...
}
Такой подход позволяет использовать best practices обеих миров и обеспечивает совместимость при миграции на App Router.
7. Типичные ошибки при работе с auth() и getServerSession()
Ошибка №1: Использование не той функции в неподходящем месте.
Часто новички пытаются использовать auth() в API Route или Page Router, что приводит к ошибке "auth() can only be used in Server Components or Server Actions". Проверьте, где вы находитесь, и используйте подходящую функцию.
Ошибка №2: Не переданы параметры в getServerSession.
getServerSession() требует req, res и authOptions. Если забыть передать хотя бы один аргумент, функция не сможет корректно получить сессию.
Ошибка №3: Несогласованность настроек authOptions.
Если настройки авторизации отличаются между API Route и App Router, возможны странные баги: например, разные провайдеры, разные session callbacks. Всегда используйте общий файл с настройками.
Ошибка №4: Ожидание, что обе функции работают на клиенте.
И auth(), и getServerSession() работают только на сервере. Для клиентских компонентов используйте useSession().
Ошибка №5: Необработка случая, когда session = null.
Сессия может отсутствовать! Не забывайте проверять, что session не равна null перед тем, как обращаться к session.user.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ