Авторизация: обзор
Авторизация отвечает на два вопроса: кто этот посетитель (вход, аутентификация) и что ему можно (права). В Next.js нет встроенной системы входа. Здесь показан самый простой рабочий вариант — сессия в куке для единственного автора блога — и сказано, когда нужна готовая библиотека.
Как устроена сессия
- Посетитель вводит пароль в форме входа.
- Сервер проверяет его, придумывает случайный идентификатор сессии и запоминает, кому он принадлежит.
- Идентификатор отправляется в браузер в куке
session. - При следующих запросах сервер читает куку и узнаёт пользователя.
Файл сессий
Создайте 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»: страница уже отправляется в браузер, и заголовки менять поздно. Записывайте куки в серверных действиях и обработчиках маршрутов, а читать их можно где угодно на сервере.