На предыдущем этапе мы создали визуальный каркас приложения на shadcn/ui. Теперь превратим статичные макеты в защищенную систему. Мы внедрим авторизацию, которая по уровню безопасности не уступает крупным сервисам, потратив на это минимум времени.
Для этого мы воспользуемся Clerk — сервисом для управления пользователями. В современных MVP выгоднее делегировать хранение паролей и сессий внешним провайдерам, чтобы сфокусироваться на уникальных функциях продукта.
Как работает современная авторизация
Разграничим два понятия, которые часто путают:
- Аутентификация — проверка личности (кто вы?). Например, вход по паролю или отпечатку пальца.
- Авторизация — проверка прав доступа (что вам разрешено?). Например, может ли пользователь редактировать этот документ.
В нашей связке Clerk проверяет личность и выдает цифровой пропуск — JWT (JSON Web Token). Это безопасный способ передачи данных о пользователе между фронтендом и бэкендом.
Как показано на Схеме 1, ключевым элементом защиты в Next.js является Middleware. Это файл-фильтр, который перехватывает каждый запрос к серверу и решает: пустить пользователя дальше или отправить на регистрацию.
Шаг 1: Настройка проекта в Clerk
Сначала получим ключи доступа:
- Зарегистрируйтесь на Clerk.
- Создайте проект (например, "My Startup MVP").
- Выберите способы входа: для быстрого старта лучше оставить Google, GitHub и Passkeys (вход по биометрии).
- В разделе API Keys скопируйте
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEYиCLERK_SECRET_KEY.
Добавьте эти ключи в файл .env.local в корне вашего проекта:
# Ключи Convex
CONVEX_DEPLOYMENT=...
NEXT_PUBLIC_CONVEX_URL=...
# Ключи Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...Шаг 2: Установка и настройка провайдера
Установите пакет интеграции через терминал:
npm install @clerk/nextjs
Оберните приложение в ClerkProvider в файле app/layout.tsx. Это даст всем компонентам доступ к статусу пользователя:
import { ClerkProvider } from '@clerk/nextjs';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ClerkProvider>
<html lang="ru">
<body>{children}</body>
</html>
</ClerkProvider>
);
}Шаг 3: Защита маршрутов через Middleware
Создайте файл middleware.ts в корне проекта. Это «фильтр», который будет охранять страницы.
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
// Список публичных страниц, доступных без входа
const isPublicRoute = createRouteMatcher(['/sign-in(.*)', '/sign-up(.*)', '/']);
export default clerkMiddleware((auth, request) => {
if (!isPublicRoute(request)) {
auth().protect(); // Защищаем все остальные страницы
}
});
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
'/(api|trpc)(.*)',
],
};Шаг 4: Оживление интерфейса
Заменим статичные кнопки на компоненты Clerk. Добавим кнопку профиля в шапку сайта:
import { SignInButton, UserButton, SignedIn, SignedOut } from "@clerk/nextjs";
export function Header() {
return (
<nav className="flex justify-between p-4 border-b">
<span>Мой Стартап</span>
<div>
{/* Видно только неавторизованным */}
<SignedOut>
<SignInButton mode="modal">
<button className="bg-black text-white px-4 py-2 rounded">Войти</button>
</SignInButton>
</SignedOut>
{/* Видно только авторизованным */}
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
</div>
</nav>
);
}Не пытайтесь проверять статус пользователя вручную через cookie или localStorage. Это приводит к ошибкам гидратации (рассинхрону данных между сервером и браузером). Используйте стандартные компоненты <SignedIn /> и <SignedOut />.
Проверка работы
- Запустите проект:
npm run dev. - Откройте браузер в режиме инкогнито.
- Попробуйте зайти на
/dashboard(или любую страницу, кроме главной). - Если Middleware работает, вас перенаправит на страницу входа.
- Войдите через Google и проверьте, появилась ли кнопка профиля.
Мы внедрили систему идентификации. Теперь приложение знает, кто к нему обращается. Однако база данных Convex пока считает эти запросы анонимными.
В следующем уроке мы научим бэкенд узнавать о новых регистрациях и сохранять профили пользователей в таблицы Convex.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram