Настройка аутентификации в Keystatic CMS (Local mode) в проекте Next.js
5 мая 2026 г.
Довольно часто, при создании лендинга или небольшого сайта, заказчик просит предоставить ему возможность самостоятельного редактирования информации на лендинге/сайте. Нет никаких проблем в том, чтобы прикрепить к лендингу/сайту какую-нибудь CMS. Но тут начинается самое интересное - устанавливать CMS, вроде Strapi, Directus, Payload или даже Wordpress, которые используют для своей работы базу данных, для лендинга или небольшого сайта - это как «из пушки во воробьям стрелять».
База данных нужна там, где необходим поиск, сортировка, выборка и др. функционал, требующий быстрой обработки больших объёмов информации. Кроме того, база данных требует выполнения сложных миграций при изменении структуры лендинга/сайта и тянет за собой увеличение расходов на поддержку, обслуживание, резервное копирование, защиту от несанкционированного доступа или взлома. И всё это ради лендинга или небольшого сайта?!
Да, опытный разработчик, при создании лендинга/сайта, может развернуть базу данных за несколько минут, а по окончании разработки передать готовый продукт заказчику и благополучно обо всём забыть, переключившись на новые задачи. А заказчику потом жить со всем этим «хозяйством» не один месяц и не один год.
К счастью, для таких кейсов есть готовые решения - CMS, не использующие для своей работы базу данных, а сохраняющие данные в файлах специальных форматов - Markdown, YAML, JSON и т.п. Но и тут не всё просто.
Долгое время я пытался найти подходящую CMS, которая соответствует следующим требованиям:
- Не использует базу данных.
- Не зависит от сторонних сервисов и может работать автономно на хостинге заказчика.
- Не требует пересборки сайта после внесения изменений и позволяет обновлять сайт в режиме реального времени.
Не могу утверждать, что я перебрал все существующие в мире CMS, но попыток было много, и все испытанные мною CMS, соответствовали только двум из трёх, перечисленных выше, требований. Даже самые близкие к моим требованиям Decap CMS и Pages CMS не умеют работать полностью автономно и требуют для своей работы интеграцию с GitHub.
Единственная CMS, которая соответствует всем трём перечисленным требованиям - это Keystatic CMS, которая может работать в двух режимах - «Github mode» и «Local mode». «Github mode» требует интеграции с CitHub, а вот «Local mode» как раз умеет работать полностью автономно.
К сожалению, Keystatic CMS в режиме «Local mode» пока не имеет встроенной аутентификации. Это означает, что аутентификацию (вход) в CMS необходимо реализовать самостоятельно. А если мы используем CMS без базы данных и без зависимостей от сторонних сервисов, то, логично, чтобы и механизм аутентификации не использовал базу данных и не зависел от сторонних сервисов, иначе какой во всём этом смысл?
Найти библиотеку аутентификации, умеющую работать без базы данных и без зависимостей от сторонних сервисов, оказалось гораздо проще, чем найти саму CMS. Выбор пал на популярную библиотеку Auth.js потому, что она отлично интегрируется с Next.js.
Настройка
1. Устанавливаем библиотеку next-auth:
npm install next-auth@beta2. В корне проекта или в папке src (если она есть) создаём файл proxy.js:
export { auth as proxy } from "@/lib/auth";
export const config = {
matcher: "/keystatic/:path*",
};3. В папке lib создаём файл auth.js:
import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { users } from "@/data/users";
const credentials = {
email: {
type: "email",
label: "Логин",
},
password: {
type: "password",
label: "Пароль",
},
};
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [
Credentials({
credentials: credentials,
authorize: (credentials) => {
return getUser(credentials);
},
}),
],
callbacks: {
authorized: ({ auth }) => {
return !!auth;
},
},
trustHost: true,
});
const getUser = (credentials) => {
if (credentials) {
const user = users[credentials.email];
if (user && user.password === credentials.password) {
return {
name: user.name,
email: credentials.email,
};
}
}
return null;
};4. И, наконец, список пользователей:
export const users = {
"gorbunkov@mail.ru": {
name: "Семён Семёныч Горбунков",
password: "...",
},
"bunsha@mail.ru": {
name: "Иван Васильевич Бунша",
password: "...",
},
};





