Разница между auth() и getServerSession() в Next.js: совместимость и нюансы

Модуль 4: Node.js, Next.js и Angular
11 уровень , 3 лекция
Открыта

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.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ