Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Авторизация: обзор

Авторизация отвечает на два вопроса: кто этот посетитель (вход, аутентификация) и что ему можно (права). В Next.js нет встроенной системы входа. Здесь показан самый простой рабочий вариант — сессия в куке для единственного автора блога — и сказано, когда нужна готовая библиотека.

Как устроена сессия

  1. Посетитель вводит пароль в форме входа.
  2. Сервер проверяет его, придумывает случайный идентификатор сессии и запоминает, кому он принадлежит.
  3. Идентификатор отправляется в браузер в куке session.
  4. При следующих запросах сервер читает куку и узнаёт пользователя.

Файл сессий

Создайте lib/session.ts. В Next.js 16 функцию cookies() из next/headers вызывают только через await:

// lib/session.ts
import { cookies } from 'next/headers';
 
const sessions = new Map<string, string>();
 
export async function createSession(user: string) {
  const id = crypto.randomUUID();
  sessions.set(id, user);
 
  const cookieStore = await cookies();
  cookieStore.set('session', id, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    path: '/',
    maxAge: 60 * 60 * 24 * 7,
  });
}
 
export async function getUser(): Promise<string | undefined> {
  const cookieStore = await cookies();
  const id = cookieStore.get('session')?.value;
  return id ? sessions.get(id) : undefined;
}

httpOnly прячет куку от JavaScript в браузере, maxAge задаёт срок жизни — неделю. Сессии лежат в памяти и пропадут при перезапуске; в настоящем проекте их хранят в таблице базы данных.

Вход

Пароль автора лежит в переменной ADMIN_PASSWORD в .env.local. Действие входа:

// app/(auth)/login/actions.ts
'use server';
 
import { redirect } from 'next/navigation';
import { createSession } from '@/lib/session';
 
export async function login(formData: FormData) {
  if (formData.get('password') !== process.env.ADMIN_PASSWORD) {
    redirect('/login');
  }
  await createSession('Анна');
  redirect('/posts/new');
}

Страница app/(auth)/login/page.tsx содержит форму <form action={login}> с полем password и кнопкой. После верного пароля браузер получит куку и откроет форму новой статьи.

Проверка прав

Прокси из прошлого урока только перенаправляет без куки. Настоящую проверку делают там, где меняются данные, — в серверном действии:

// app/posts/actions.ts (фрагмент)
const user = await getUser();
if (!user) {
  redirect('/login');
}

Так статью не добавит даже тот, кто вызовет действие в обход формы.

Когда брать библиотеку

Вход через Google или GitHub, регистрация многих пользователей, сброс пароля — это много кода, где легко ошибиться. Для таких задач берут Auth.js (пакет next-auth) или готовые сервисы вроде Clerk. Пароли пользователей хранят только в виде хеша, например через bcrypt.

Частая ошибка

Устанавливать куку в серверном компоненте страницы. Next.js выдаст ошибку «Cookies can only be modified in a Server Action or Route Handler»: страница уже отправляется в браузер, и заголовки менять поздно. Записывайте куки в серверных действиях и обработчиках маршрутов, а читать их можно где угодно на сервере.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.