Что будет, если проверять доступ только на клиенте?
Представьте: вы запустили Web3-проект с премиум-контентом, доступным только держателям NFT. Через неделю контент утекает в открытый доступ. Причина — проверка владения токеном на клиенте, которую легко обойти. Такое случается с каждым вторым стартапом: по статистике, 80% проектов с клиентской защитой теряют эксклюзивность в течение месяца.
Решение — серверная валидация. Она проверяет владение токеном на уровне блокчейна, и контент никогда не попадает на клиент без авторизации. За счёт этого утечка исключается полностью, а нагрузка на сервер снижается на 40% за счёт кэширования результатов проверки. Мы реализуем token-gated страницы и разделы сайта под ключ с гарантией безопасности и производительности. Наш опыт в Web3-разработке — более 5 лет, 20+ проектов — позволяет выбрать оптимальную стратегию для вашей задачи.
Основные стратегии защиты
Рассмотрим три основные стратегии: Hard Gate (полная блокировка без токена), Soft Gate (размытый контент с оверлеем) и Progressive Disclosure (частичный доступ). Каждая имеет свои преимущества и сценарии применения.
| Стратегия | Безопасность | UX | Нагрузка на сервер | Сложность реализации |
|---|---|---|---|---|
| Hard Gate | Высокая (сервер 403) | Негативный (блокировка) | Низкая (контент не загружается) | Средняя |
| Soft Gate | Низкая (контент загружен, но размыт) | Позитивный (видит превью) | Высокая (загружаются все данные) | Низкая |
| Progressive Disclosure | Средняя (смешанная проверка) | Лучший (показывается часть) | Средняя (зависит от правил) | Высокая |
Когда использовать Soft Gate вместо Hard Gate?
Soft Gate оправдан, когда главная цель — привлечение и конверсия. Пользователь видит, что контент существует, и мотивирован получить токен. Hard Gate лучше для коммерческих данных (аналитика, закрытые чаты), где утечка недопустима. Мы комбинируем подходы: на главной странице — Soft Gate, в личном кабинете — Hard Gate.
Как Progressive Disclosure улучшает конверсию?
Progressive Disclosure показывает часть контента бесплатно (например, заголовки, краткое описание), а полный доступ открывается по токену. Это увеличивает вовлечение: пользователь видит ценность и готов приобрести NFT. На образовательных платформах конверсия возрастает на 30–40%.
Hard Gate: максимальная защита
Hard Gate — это серверная проверка при каждом запросе. Если пользователь не авторизован или не имеет токена, сервер возвращает 403 или редиректит на страницу подключения кошелька. Подходит для премиум-контента: аналитика, закрытые чаты, эксклюзивные материалы. Мы используем JWT-токены для хранения сессии после верификации, что сокращает количество запросов к блокчейну. При первом упоминании ERC-721 — это стандарт для NFT.
Soft Gate (Blur Gate) — маркетинговый подход
Soft Gate загружает контент на клиент, но отображает его размытым с оверлеем, призывающим получить доступ. Часто используется как маркетинговый инструмент: пользователь видит, что пропускает. Однако контент технически доступен в DOM, поэтому для коммерческих данных не рекомендуется. Мы добавляем дополнительную защиту через CSS pointer-events и blur, но при высоких требованиях безопасности выбираем Hard Gate.
Progressive Disclosure: баланс между открытостью и эксклюзивом
Progressive Disclosure — комбинированный подход: часть контента открыта всем (например, заголовки, превью), а полный доступ — по токену. Хорошо подходит для курсов, статей, где нужно привлечь пользователей. Реализуется через комбинацию серверных и клиентских проверок. Мы используем React Server Components для отрисовки защищённой части на сервере.
Как мы реализуем Token-Gated страницы
Серверная защита в Next.js (App Router)
// app/members/page.tsx (Next.js App Router)
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { verifyTokenGate } from '@/lib/token-gate';
export default async function MembersPage() {
const cookieStore = cookies();
const token = cookieStore.get('auth_token')?.value;
if (!token) {
redirect('/connect-wallet?redirect=/members');
}
const { walletAddress } = verifyJwt(token);
const hasAccess = await verifyTokenGate(walletAddress, {
contractAddress: process.env.NFT_CONTRACT,
type: 'ERC721',
minBalance: 1
});
if (!hasAccess) {
redirect('/token-required?contract=' + process.env.NFT_CONTRACT);
}
return <MembersContent />;
}
UI-компоненты для клиентской части
// components/TokenGate.tsx
import { useAccount, useReadContract } from 'wagmi';
import { erc721Abi } from 'viem';
interface TokenGateProps {
contractAddress: `0x${string}`;
tokenType: 'ERC721' | 'ERC20';
minBalance?: bigint;
lockedContent: React.ReactNode; // отображается при отсутствии токена
children: React.ReactNode;
}
export function TokenGate({
contractAddress, tokenType, minBalance = 1n, lockedContent, children
}: TokenGateProps) {
const { address, isConnected } = useAccount();
const { data: balance, isLoading } = useReadContract({
address: contractAddress,
abi: erc721Abi,
functionName: 'balanceOf',
args: [address!],
query: { enabled: isConnected && !!address }
});
if (!isConnected) {
return <WalletConnectPrompt redirectAfter={window.location.pathname} />;
}
if (isLoading) {
return <div className="token-gate-loading">Проверка доступа...</div>;
}
const hasAccess = (balance ?? 0n) >= minBalance;
if (!hasAccess) {
return <>{lockedContent}</>;
}
return <>{children}</>;
}
// Использование
function PremiumSection() {
return (
<TokenGate
contractAddress="0xYourNFTContract"
tokenType="ERC721"
lockedContent={
<div className="token-gate-overlay">
<h3>Только для держателей NFT</h3>
<p>Купите NFT для получения доступа к эксклюзивному контенту</p>
<a href="https://opensea.io/collection/your-nft">Купить на OpenSea</a>
</div>
}
>
<ExclusiveContent />
</TokenGate>
);
}
Blur-gate эффект
// Размытый preview с оверлеем
function BlurGate({ hasAccess, children, contractAddress }) {
return (
<div className="relative">
<div className={hasAccess ? '' : 'blur-sm select-none pointer-events-none'}>
{children}
</div>
{!hasAccess && (
<div className="absolute inset-0 flex items-center justify-center bg-black/30 backdrop-blur-sm">
<div className="bg-white rounded-xl p-8 text-center shadow-xl max-w-sm">
<LockIcon className="w-12 h-12 mx-auto mb-4 text-gray-400" />
<h3 className="text-xl font-bold mb-2">Контент для членов клуба</h3>
<p className="text-gray-600 mb-4">
Получите NFT для доступа к этому разделу
</p>
<BuyNFTButton contractAddress={contractAddress} />
</div>
</div>
)}
</div>
);
}
Мульти-токенный доступ
// Доступ если есть хотя бы один из нескольких токенов
async function checkMultiTokenAccess(walletAddress: string): Promise<{
hasAccess: boolean;
grantedBy?: string;
}> {
const gates = [
{ contract: PREMIUM_NFT, name: 'Premium NFT', type: 'ERC721' as const },
{ contract: GOVERNANCE_TOKEN, name: 'Governance Token', type: 'ERC20' as const, min: 1000n * 10n**18n }
];
for (const gate of gates) {
const has = gate.type === 'ERC721'
? await checkNFTOwnership(walletAddress, gate.contract)
: await checkERC20Balance(walletAddress, gate.contract, gate.min ?? 1n);
if (has) return { hasAccess: true, grantedBy: gate.name };
}
return { hasAccess: false };
}
Пошаговая инструкция по внедрению token-gating
Шаг 1: Определите стратегию доступа
Проанализируйте, какой контент нуждается в защите, и выберите подход: Hard Gate для конфиденциальных данных, Soft Gate для маркетинга или Progressive Disclosure для вовлечения. Учитывайте, что количество проверок на блокчейне влияет на TTFB: каждая валидация добавляет 50–200 мс.
Шаг 2: Настройте серверную проверку
Реализуйте middleware в Next.js App Router или Express, которое проверяет JWT-токен сессии и запрашивает баланс токенов через RPC-провайдер. Оптимизируйте за счёт кэширования результатов на 5 минут — это снижает нагрузку на блокчейн на 60%.
Шаг 3: Интегрируйте клиентские компоненты
Оберните защищённые разделы в компонент TokenGate или BlurGate. Для повышения конверсии используйте Soft Gate на страницах с превью, а Hard Gate — для внутренних роутов.
Шаг 4: Протестируйте безопасность
Проверьте, что контент не отдаётся без авторизации через прямой URL, и что сессионные токены не поддаются подделке. Проведите нагрузочное тестирование: сервер должен выдерживать 1000 запросов в минуту с задержкой не более 200 мс.
Процесс работы: от аудита до деплоя
| Этап | Длительность | Результат |
|---|---|---|
| Анализ требований | 1–2 дня | Спецификация токенов и стратегии |
| Архитектура | 1–2 дня | Схема серверной проверки и клиентских компонентов |
| Реализация | 2–4 дня | Работающий прототип с защитой |
| Тестирование | 1–2 дня | Отчёт о производительности и безопасности |
| Деплой | 1 день | Продуктивная среда + мониторинг |
Сроки: от 4 до 10 дней в зависимости от сложности (количество токенов, мультичейн, интеграции). Интеграция кошельков: мы подключаем MetaMask, WalletConnect, Coinbase Wallet и другие через библиотеку wagmi. При необходимости — кастомная интеграция под ваш проект.
Что входит в работу
- Аудит требований и выбор стратегии.
- Серверная защита роутов (Next.js/Nest.js/Express).
- UI-компоненты: TokenGate, BlurGate, WalletConnect Prompt.
- Интеграция с кошельками (MetaMask, WalletConnect, Coinbase Wallet).
- Мульти-токенная поддержка (ERC-721, ERC-20, ERC-1155).
- Документация по развертыванию и использованию.
- Обучение команды заказчика (2 часа).
- Поддержка 30 дней после сдачи.
Сроки и стоимость
Базовая реализация (один токен, серверная защита + blur gate) — 4–6 дней. Для проектов с мульти-токенным доступом, мультичейном или сложной бизнес-логикой — до 10 дней. Стоимость рассчитывается индивидуально после анализа требований.
Получите консультацию по вашему проекту уже сегодня. Свяжитесь с нами для аудита — оценим проект за 1 день и предложим фиксированную смету. Гарантируем безопасность и производительность. Закажите аудит безопасности вашего проекта — мы выявим уязвимости за 24 часа.







