История такова: я всегда хотел, чтобы мое резюме было общедоступным для скачивания, а затем я мог разместить его на страницах своего профиля и т. Д., Но я не хочу, чтобы мошенники рассылали спам. Я придумал cgar несколько лет назад, это довольно сложно и требует kubernetes для размещения, я сразу же прекратил его использовать, как только закончился мой бесплатный кредит в Linode. Недавно я снова взялся за поиск работы и воссоздал диспенсер резюме (github), свободно размещенный на CloudFlare.
Шаг 1: Турникет CloudFlare
Я заметил, что OpenAI использует человеческие шашки от CloudFlare, и решил попробовать. Это бесплатно и довольно просто в использовании, и они предоставляют отличные примеры, такие как проверка на стороне сервера (github).
// This is the demo secret key. In production, we recommend // you store your secret key(s) safely. const SECRET_KEY = '1x0000000000000000000000000000000AA'; async function handlePost(request) { const body = await request.formData(); // Turnstile injects a token in "cf-turnstile-response". const token = body.get('cf-turnstile-response'); const ip = request.headers.get('CF-Connecting-IP'); // Validate the token by calling the // "/siteverify" API endpoint. let formData = new FormData(); formData.append('secret', SECRET_KEY); formData.append('response', token); formData.append('remoteip', ip); const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'; const result = await fetch(url, { body: formData, method: 'POST', }); const outcome = await result.json(); if (outcome.success) { // ... } }
Комментарии
- Не забудьте добавить домены после развертывания.
Шаг 2: Воркеры CloudFlare
Давайте немного отступим для общей картины с некоторой редукционистской логикой.
- Нам нужно разместить файл (резюме) для скачивания. Само по себе это тривиально, мы можем просто выложить на гитхаб.
- Нам нужно проверить на человека, это диктует, что мы предоставляем страницу с CAPTCHA. Как только человек проходит захват, мы разрешаем ему загрузку.
- Как хост, выполняющий загрузку, как я узнаю, что CAPTCHA прошла успешно? Обычно мы помещаем CAPTCHA на страницу входа в систему, после успешного входа пользователь затем запросит загрузку с подписанным токеном.
- Мы являемся общедоступной ссылкой (резюме), вход пользователя в систему невозможен, поэтому мы можем выдавать подписанные токены любому, кто проходит CAPTCHA.
Это приемлемое решение, мы можем реализовать get и post со следующей спецификацией.
- ПОЛУЧИТЬ: если подписанный токен действителен, вернуть файл. Если токен подписи отсутствует или недействителен, верните форму CAPTCHA.
- POST: проверьте форму CAPTCHA и верните подписанный токен в виде файла cookie.
Я заметил, что часть токена можно опустить, если мы изменим спецификацию.
- ПОЛУЧИТЬ: вернуть форму CAPTCHA.
- POST: проверьте форму CAPTCHA и верните файл.
Я не уверен, нарушает ли какие-либо законы Интернета передача файла по почтовому звонку, но ладно. Моим любимым бесплатным хостингом раньше был netlify, netlify тоже предоставляет воркеры, но с одной смертельной слабостью: хуки воркеров завернуты и могут использовать только JSON в качестве ввода/вывода, то есть невозможно инициировать загрузку в браузере. Я мог бы вернуть содержимое файла в кодировке base64, а затем иметь некоторую логику на стороне клиента для его декодирования (есть множество других трюков, которые мы можем сделать, если зафиксируем полноценный интерфейс), но мои новые любимые рабочие CloudFlare универсальны и экономят мне беда. Он также поставляется с отличным серверным примером для Turnstile (github).
Комментарии по модификации примера (github)
wrangler dev
отлично, он настраивает локальный сервер для тестирования.- Используйте
env.TURNSTILE_SECRET
для получения секретов в коде. - Используйте
wrangler secret put TURNSTILE_SECRET
, чтобы поместить секреты в CloudFlare. - Используйте
.dev.vars
, чтобы предоставить секреты для локального сервера. "1x0000000000000000000000000000000AA"
— это специальный секретный ключ в Turnstile for dev.wrangler publish
угадайте, что это делает.- Измените HTML-страницу, указав правильный открытый ключ турникета.
Шаг 3: Актив CloudFlare и KV
Мы почти закончили! Теперь структура управления на месте, осталось только подать файл (это CloudFlare, если он что-то делает, то это вещь), я нашел хороший пример (github)
import { getAssetFromKV } from '@cloudflare/kv-asset-handler'; import manifestJSON from '__STATIC_CONTENT_MANIFEST'; const assetManifest = JSON.parse(manifestJSON); export default { async fetch(request, env, ctx) { try { // Add logic to decide whether to serve an asset or run your original Worker code return await getAssetFromKV( { request, waitUntil: ctx.waitUntil.bind(ctx), }, { ASSET_NAMESPACE: env.__STATIC_CONTENT, ASSET_MANIFEST: assetManifest, } ); } catch (e) { let pathname = new URL(request.url).pathname; return new Response(`"${pathname}" not found`, { status: 404, statusText: 'not found', }); } }, };
Комментарии по модификации примера (github)
- Поместите активы в папку
./public
. Обратите внимание, что я не размещал активы на github, потому что это противоречит цели их защиты с помощью человека-чекера. getAssetFromKV
делает всю тяжелую работу за нас, нам просто нужно предоставить ему объектrequest
с URL-адресом, который имеет путь, который сопоставляется с активом. Обратите внимание, что мне пришлось воссоздать объектrequest
с методомGET
.- Наши активы кэшируются в KV, то есть в базе данных. Это означает, что мы можем зайти в консоль CloudFlare и вручную изменить обслуживаемый файл (до тех пор, пока он не будет переопределен при следующем развертывании).
Оригинал: https://bettercallshao.com/share-resume-with-humans-not-bots/