Быстрая настройка авторизации через Clerk

На предыдущем этапе мы создали визуальный каркас приложения на shadcn/ui. Теперь превратим статичные макеты в защищенную систему. Мы внедрим авторизацию, которая по уровню безопасности не уступает крупным сервисам, потратив на это минимум времени.

Для этого мы воспользуемся Clerk — сервисом для управления пользователями. В современных MVP выгоднее делегировать хранение паролей и сессий внешним провайдерам, чтобы сфокусироваться на уникальных функциях продукта.

Как работает современная авторизация

Разграничим два понятия, которые часто путают:

  1. Аутентификация — проверка личности (кто вы?). Например, вход по паролю или отпечатку пальца.
  2. Авторизация — проверка прав доступа (что вам разрешено?). Например, может ли пользователь редактировать этот документ.

В нашей связке Clerk проверяет личность и выдает цифровой пропуск — JWT (JSON Web Token). Это безопасный способ передачи данных о пользователе между фронтендом и бэкендом.

Как показано на Схеме 1, ключевым элементом защиты в Next.js является Middleware. Это файл-фильтр, который перехватывает каждый запрос к серверу и решает: пустить пользователя дальше или отправить на регистрацию.

Шаг 1: Настройка проекта в Clerk

Сначала получим ключи доступа:

  1. Зарегистрируйтесь на Clerk.
  2. Создайте проект (например, "My Startup MVP").
  3. Выберите способы входа: для быстрого старта лучше оставить Google, GitHub и Passkeys (вход по биометрии).
  4. В разделе 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 />.

Проверка работы

  1. Запустите проект: npm run dev.
  2. Откройте браузер в режиме инкогнито.
  3. Попробуйте зайти на /dashboard (или любую страницу, кроме главной).
  4. Если Middleware работает, вас перенаправит на страницу входа.
  5. Войдите через Google и проверьте, появилась ли кнопка профиля.

Мы внедрили систему идентификации. Теперь приложение знает, кто к нему обращается. Однако база данных Convex пока считает эти запросы анонимными.

В следующем уроке мы научим бэкенд узнавать о новых регистрациях и сохранять профили пользователей в таблицы Convex.

Понравился урок?

Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей

Продолжить в Telegram