Як ми створюємо безпечні списки очікування для beta на Cloudflare
Tech
Cloudflare Workers
Beta Waitlist
Double Opt-In
Turnstile

Як ми створюємо безпечні списки очікування для beta на Cloudflare

Практичний метод створення готових до production списків очікування для beta на Cloudflare із подвійним підтвердженням згоди, Turnstile, хешованими токенами, SMTP, елементами керування для адміністраторів і release gates.

Uygar DuzgunUUygar Duzgun
Jul 26, 2026
Оновлено 20 серп. 2026 р.
9 min read

Як ми створюємо безпечні списки очікування для beta на Cloudflare

Список очікування для beta є бізнес-активом лише тоді, коли адреси в ньому справжні.

Більшість команд починають з одного поля email і кнопки надсилання. Для експерименту з landing page цього достатньо. Але цього недостатньо, коли список починає впливати на плани запуску, хвилі запрошень, оновлення для інвесторів або продуктові рішення. Якщо будь-хто може надіслати чужу адресу або бот може заповнити базу за одну ніч, команда отримує зашумлений попит замість корисного сигналу.

Це метод, який я використовую для створення готового до production списку очікування для beta на Cloudflare: подвійне підтвердження згоди, серверні перевірки ботів, короткоживучі посилання для підтвердження, хешовані токени, надсилання через SMTP із наявного поштового хостингу, налаштування адміністрування, які розділяють підтверджені та застарілі записи, а також release gate, який не видає налаштовану інфраструктуру за вже запущену.

Нещодавня реалізація списку очікування для beta підтвердила цей метод у реальному delivery без потреби в повноцінній системі облікових записів. Корисною є сама структура роботи: невелика поверхня реєстрації з чіткими межами навколо згоди, зловживань, доставки, якості даних і deployment.

Бізнес-проблема, яку вирішує безпечний список очікування

Список очікування має два завдання.

Він має збирати попит і допомагати команді діяти на основі цього попиту. Саме на другій частині слабкі форми зазнають невдачі.

Якщо ви не можете довіряти списку, кожна подальша дія стає повільнішою. Ви замислюєтеся, скільки записів створили боти. Вагаєтеся перед надсиланням листів із запрошеннями. Експортуєте дані, очищуєте їх вручну й усе одно не знаєте, чи контролює людина цю адресу. Список перетворюється на приблизну vanity metric замість інструмента для release.

Безпечний список очікування для beta дає чистіші вхідні дані:

менше фальшивих реєстрацій від ботів або скриптів
менше адрес, надісланих без згоди
кращий доказ того, що людина контролює inbox
зрозуміліші admin exports для запуску та комунікації
менше ручного очищення перед надсиланням запрошень до beta
безпечніший шлях deployment до появи публічного трафіку

Мета не в тому, щоб ускладнити просту форму. Мета — зробити так, щоб форма означала саме те, що, на думку бізнесу, вона означає.

Архітектура Cloudflare

Основний стек навмисно невеликий.

Cloudflare Workers обробляють запит. Cloudflare Turnstile перевіряє, чи схожа реєстрація на людську. D1 зберігає записи списку очікування та незавершені підтвердження. Наявний SMTP/mailhosting надсилає email із підтвердженням через TLS. Заплановане завдання очищення Worker видаляє прострочені незавершені записи.

Цього стеку достатньо для багатьох команд на ранній стадії. Не потрібно додавати повноцінну систему облікових записів лише для того, щоб зібрати відповідальний список beta.

Процес виглядає так:

Відвідувач надсилає email через форму списку очікування.
Worker перевіряє origin, розмір body, honeypot, rate limits і Turnstile.
Worker створює незавершене підтвердження зі строком дії 24 години.
Необроблений токен потрапляє в посилання email, але D1 зберігає лише keyed hash.
Користувач відкриває посилання та підтверджує його через same-origin POST.
Worker використовує одноразовий токен і записує підтверджений рядок у список очікування.
Admin views і CSV exports за замовчуванням показують підтверджені адреси.

Це дає продуктовим командам чітке розділення: незавершений інтерес — не те саме, що підтверджений попит.

Подвійне підтвердження згоди — це продуктове рішення

Подвійне підтвердження згоди часто розглядають як гігієну email. Я вважаю це продуктовою гігієною.

Якщо список beta визначатиме, хто отримає доступ першим, команда має знати, що кожна адреса належить людині, яка її підтвердила. Вікна підтвердження тривалістю 24 години достатньо для звичайної реєстрації, і воно достатньо коротке, щоб застарілі незавершені записи не залишалися надовго.

Посилання для підтвердження не повинно самостійно змінювати стан. Існують сканери посилань, попередній перегляд email і випадкові GET-запити. Безпечніший підхід — дозволити посиланню відобразити сторінку підтвердження, а потім вимагати від користувача натиснути кнопку, яка надсилає same-origin POST.

Цей додатковий клік незначний. Межа, яку він створює, корисна.

Це також спрощує підтримку. Якщо хтось каже, що не реєструвався, ви можете послатися на процес, який вимагав доступу до inbox і явної дії підтвердження, перш ніж адреса потрапила до підтвердженого списку.

Захист від ботів без ворожої форми

Хороший список очікування не має нагадувати іспит із безпеки.

Захист переважно має працювати за лаштунками форми. У цій реалізації Worker перевіряє віджет Cloudflare Turnstile на стороні сервера. Перевірка охоплює токен, очікувану action і очікуваний hostname. Browser widget без серверної перевірки — лише декорація; Worker має виконувати верифікацію.

Turnstile — лише один рівень. Форма також використовує поле honeypot для недорогого виявлення ботів, обмежений request body, щоб надмірні payloads не витрачали час Worker, keyed IP rate limiting і keyed обмеження спроб для кожної адреси.

Обмеження для кожної адреси важливе, оскільки підтвердження email може стати інструментом для створення незручностей. Ви не хочете, щоб хтось постійно запускав надсилання листів із підтвердженням до одного inbox.

Публічна відповідь залишається загальною. Вона не повинна розкривати, чи адреса вже існує, очікує підтвердження, перебуває в списку блокування або досягла ліміту. Це не дає перетворити endpoint реєстрації на інструмент email enumeration.

Зберігання токенів: хешуйте те, що надсилаєте

Посилання для підтвердження є чутливими, оскільки доводять доступ до inbox.

Реалізація надсилає випадковий токен у посиланні email, але D1 зберігає лише keyed hash цього токена. Під час підтвердження Worker хешує надісланий токен і порівнює його зі збереженим хешем. Необроблений токен не зберігається в базі даних.

Такий дизайн зберігає систему простою та зменшує потенційний масштаб наслідків. Якщо таблиця незавершених підтверджень витече, зловмисник не отримає готових до використання посилань для підтвердження.

Токен є одноразовим. Після успішного підтвердження Worker видаляє незавершений запис. Прострочені незавершені записи очищуються під час звичайної роботи зі списком очікування та через щоденний Cloudflare Cron.

Цей шлях очищення зберігає таблицю невеликою без ручної роботи з базою даних.

Доставка email через наявний mailhosting

Багато команд уже мають mailhosting. Їм не завжди потрібен новий transactional email vendor для списку очікування beta.

У реалізації, яку я перевірив, на наявному mailhosting було створено окрему адресу відправника, а Worker надсилає листи через SMTP over TLS. Email простий: підтвердьте реєстрацію до beta, посилання дійсне 24 години, проігноруйте його, якщо ви цього не запитували.

Для цього завдання цього достатньо.

Цінність не в складному дизайні email. Цінність — у відомому відправнику, вузькому призначенні та шляху доставки, який можна перевірити smoke test перед запуском. Для startup це часто краще, ніж додавати ще одного vendor до того, як у продукту з’являться користувачі.

Admin views мають захищати команду від хибних припущень

Безпека — це не лише публічний endpoint.

Admin view має відображати data contract. Підтверджені адреси повинні показуватися за замовчуванням. Старі непідтверджені або legacy-записи можуть залишатися доступними, але для них потрібен явний фільтр. CSV export має дотримуватися того самого правила.

Це запобігає поширеній помилці під час запуску: експортувати кожен історичний запис і сприймати його як підтверджений попит.

У нещодавній реалізації production-список уже містив legacy-адреси до появи нової моделі підтвердження. План міграції зберігає ці адреси як legacy-записи. Він не позначає старі записи мовчки як підтверджені лише тому, що нова система тепер має стан verified.

У цьому полягає різниця між міграцією та переписуванням історії.

Налаштовано — не означає запущено

Ця межа є частиною сервісу, який я надав би іншій команді.

Поштова скринька може існувати. Віджет Turnstile може існувати. Назви секретів Worker можуть бути налаштовані. Тести можуть проходити. Ніщо з цього не означає, що публічний сайт уже працює з новим списком очікування.

Для поточної reference implementation flow подвійного підтвердження згоди реалізовано та локально перевірено. Pending D1 migration, нова версія Worker і запланований cleanup Cron усе ще потребують release approval і deployment. Публічний сайт і далі використовує стару форму списку очікування, доки це не станеться.

Це розмежування захищає бізнес. D1 migration змінює структуру production-даних. Worker deploy змінює поведінку реєстрації. Cron додає фонову зміну даних. Кожен крок потребує явного release window, перевірки та продуманого rollback.

Безпечний список очікування не слід запускати недбало лише тому, що до нього прикріплено слово secure.

Як виглядає перевірка

Для delivery готового до production списку очікування я хочу мати докази до запуску.

Reference implementation пройшла 150 тестів. Astro check повідомив про 0 помилок. Production build завершився успішно. Робота стосувалася лише web, тому наявні зміни native app залишилися недоторканими.

Release checklist усе одно має значення після цього:

навмисно застосувати additive D1 migration
розгорнути саме ту версію Worker, яка призначена для release
підтвердити, що віджет Turnstile відображається на live domains
надіслати одну власну email-адресу через live form
перевірити доставку SMTP від окремого відправника
підтвердити через same-origin POST
використати токен вдруге та переконатися, що операція завершується помилкою
перевірити очищення прострочених незавершених записів
перевірити, що admin defaults і CSV exports спочатку показують підтверджені записи

У цьому полягає різниця між «код компілюється» та «воронка реєстрації готова до трафіку».

Де це допомагає startup

Цей підхід корисний, коли команда наближається до beta, але ще не готова до повноцінних облікових записів.

Можливо, ви запускаєте mobile app, SaaS-інструмент, приватну alpha-версію, обмежену AI-функцію або список резервування hardware. Вам потрібно збирати попит, але також потрібні чисті дані та згода, перш ніж починати надсилати запрошення.

Безпечний Cloudflare waitlist дає це без додавання великого backend:

Workers для межі обробки запитів
Turnstile для серверно перевіреного захисту від ботів
D1 для підтверджених записів і незавершених підтверджень
наявний SMTP для доставки
rate limits і перевірки honeypot для контролю зловживань
admin filters і exports, що відповідають data contract
release gate, який розділяє налаштовану інфраструктуру та live production behavior

Він достатньо малий, щоб швидко його запустити, і достатньо суворий, щоб йому довіряти.

Потрібно це для вашого продукту?

Я можу допомогти спроєктувати, захистити або реалізувати такий flow реєстрації для продуктової команди.

Корисна робота — не просто додати CAPTCHA до форми. Вона полягає у визначенні того, що означає реєстрація, як доводиться згода, де зберігаються токени, як доставляється email, що адміністратори бачать за замовчуванням і як перевіряється release до того, як на нього потрапить публічний трафік.

Якщо ваш список beta ось-ось стане частиною плану запуску, варто зробити його надійним до того, як ви почнете використовувати його для ухвалення рішень.