Пошаговые инструкции Для начинающих 11 мин

Как защитить Webhook в n8n через Header Auth

Настройте секретный заголовок и проверьте доступ с ключом и без него. 10 шагов, готовый workflow, ответы 200/403 и важное предупреждение об истории.

n8n webhook Header Auth

Случайное имя Webhook не заменяет проверку доступа. Настроим в n8n Header Auth: правильный секрет в заголовке пропустит GET-запрос, отсутствующий или неверный — остановит его до рабочих узлов. Проверим оба результата на отдельном учебном workflow.

Результат инструкции

Соберём схему из трёх узлов. Protected Request проверяет заголовок X-Ezgpt-Key через credentials n8n. При совпадении Build Reply создаёт короткий учебный ответ, а Send Reply возвращает его клиенту. В проверенной версии правильный ключ даёт HTTP 200, неправильный или отсутствующий — 403.

Используем только локальный Test URL, workflow не публикуем. Ключ создаёте вы и храните отдельно от публичного workflow. Никакие базы, документы и внешние API схема не открывает. Header Auth проверяет владение одним общим секретом, но не распределяет права между пользователями и не заменяет HTTPS.

Что понадобится

  • Локальный n8n и новый учебный workflow. Проверено на n8n 2.42.4, Webhook 2.1 и Respond to Webhook 1.4.
  • Windows PowerShell для генерации секрета и тестового запроса. Пример URL использует порт 5679; подставьте адрес своего n8n.
  • Возможность создать Header Auth credential. Настоящие ключи других сервисов для этого примера не нужны.

Установить n8n локально через Docker

Шаг 1. Импортируйте учебную схему

Скачать n8n-webhook-header-auth.json

Создайте отдельный workflow и загрузите JSON через Import from File. В схеме должны быть три узла:

text
Protected Request → Build Reply → Send Reply

Protected Request — Webhook, Build Reply — Code, Send Reply — Respond to Webhook. Схема неактивна. В ней намеренно нет credentials, их ID и значения ключа: после импорта вы должны выбрать собственный credential. Не меняйте Authentication на None, чтобы убрать предупреждение о недостающем credential.

Шаг 2. Создайте отдельный случайный ключ

Откройте PowerShell и выполните:

powershell
$bytes = New-Object byte[] 32
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($bytes)
$rng.Dispose()
$secret = ([BitConverter]::ToString($bytes)).Replace("-", "").ToLowerInvariant()
$secret

В окне появится строка из 64 шестнадцатеричных символов, созданная из 32 случайных байт. Сохраните её в своём менеджере секретов и оставьте это окно PowerShell открытым: переменная $secret понадобится для запроса. Это новый секрет только для учебного Webhook, не пароль от n8n и не API-ключ OpenAI.

Не присылайте ключ в чат, не помещайте его в статью, имя credential, URL или скриншот. Вывод в PowerShell тоже чувствителен: не публикуйте снимок этого окна. Если используете уже опубликованный пример ключа, он больше не является секретом.

Шаг 3. Создайте Header Auth credential

В Protected Request выберите Authentication: Header Auth. В выборе credential создайте новый Header Auth credential. Назовите его, например, ezGPT local webhook key. Это название только для вашего удобства, в нём не должно быть самого секрета.

В поле Name укажите X-Ezgpt-Key. В Value вставьте созданную строку без кавычек и лишних пробелов. Сохраните credential и убедитесь, что именно он выбран в Webhook. Name — имя HTTP-заголовка, Value — его секретное значение; это два разных поля.

Для этого примера сервис не выдаёт вам готовый ключ: вы задаёте его сами и затем передаёте тот же секрет в запросе. Credentials хранят настройку проверки, но сами по себе не гарантируют отсутствие секрета в данных входящего запроса и истории выполнения.

Шаг 4. Сверьте параметры Webhook

Поле Значение Проверка
HTTP Method GET Команда должна отправлять GET
Path ezgpt-header-auth-demo Путь из Test URL
Authentication Header Auth Выбран созданный credential
Respond Using Respond to Webhook node Ответ вернёт Send Reply

Оставьте Options без дополнительных условий. Не заменяйте Header Auth самодельной проверкой $json.headers в Code: тогда запрос уже дошёл бы до workflow. Здесь используется встроенная проверка Webhook до выполнения Build Reply.

Не рассматривайте CORS как замену секрету. Ограничение браузерных источников и проверка значения заголовка решают разные задачи; запрос из curl не становится доверенным из-за настройки CORS.

Шаг 5. Настройте короткий ответ без секрета

В Build Reply выберите Run Once for All Items, JavaScript и оставьте код:

javascript
return [{ json: { status: 'ok', test: 'header-auth-demo', action: false } }];

Код не возвращает headers, query, body и credentials. Не используйте для ответа весь вход Webhook: в нём могут оказаться чувствительные значения. В Send Reply задайте Respond With: First Incoming Item, Response Code: 200. В Response Headers добавьте Cache-Control: no-store.

В Settings узлов оставьте On Error: Stop Workflow. Никаких действий с рабочими данными между Webhook и ответом не добавляйте. Статус ok — просто тело учебного ответа; доказательство работы авторизации — пара тестов с правильным и отсутствующим ключом.

Шаг 6. Включите ожидание Test URL

Сохраните workflow, выберите Test URL в Protected Request и нажмите Listen for test event или Execute workflow. Workflow должен ждать входящий запрос. Публиковать его не нужно.

Скопируйте фактический Test URL. В командах ниже используется http://localhost:5679/webhook-test/ezgpt-header-auth-demo. Если у вашего экземпляра другой адрес, замените его. HTTP в этой статье относится только к loopback на собственном компьютере; для передачи ключа через сеть нужен HTTPS с проверкой сертификата.

Test URL работает только при активном ожидании. В проверенном тестовом режиме после успешного запроса нужно снова запустить слушатель. Production URL у неопубликованной схемы не зарегистрирован. Ошибку 404 не нужно исправлять заменой секрета: сначала проверьте URL, метод и ожидание.

Шаг 7. Отправьте правильный ключ

В том же окне PowerShell, где создана переменная $secret, выполните:

powershell
$testUrl = "http://localhost:5679/webhook-test/ezgpt-header-auth-demo"
Invoke-RestMethod -Method Get -Uri $testUrl -Headers @{ "X-Ezgpt-Key" = $secret } | ConvertTo-Json

Ожидается HTTP 200 и такой JSON:

json
{
  "status": "ok",
  "test": "header-auth-demo",
  "action": false
}

В редакторе должны выполниться Build Reply и Send Reply. В ответе не должно быть ключа и входных заголовков. Если открыли новое окно PowerShell, переменная $secret там не задана: не создавайте случайный новый ключ, оставив старый Value в credential, иначе значения не совпадут.

Пример использует встроенный HTTP-клиент PowerShell, поэтому реальный ключ не подставляется в командную строку отдельного процесса curl.exe. Всё равно обращайтесь с переменной и credential как с секретом: не выводите их в общий лог и не используйте на чужом компьютере.

Шаг 8. Проверьте запрос без ключа и с неправильным значением

Убедитесь, что тестовое ожидание активно; после успешного GET включите его заново. Для запроса без ключа выполните:

powershell
curl.exe --include --max-time 15 "$testUrl"

В проверенной версии ожидается HTTP 403. Build Reply и Send Reply не должны выполниться для этого запроса. Если тестовый слушатель уже выключен, сначала восстановите ожидание: 404 не проверяет авторизацию.

Для неправильного значения заголовка, при активном ожидании, выполните:

powershell
curl.exe --include --max-time 15 "$testUrl" --header "X-Ezgpt-Key: not-the-key"

Ожидается тот же 403 и отсутствие выполнения рабочих узлов. В этих командах --fail не используется, чтобы было удобно увидеть статус отказа. not-the-key — открытая строка для отрицательного теста, не ваш настоящий секрет.

Запрос Ожидаемый статус Рабочие узлы
Правильный X-Ezgpt-Key 200 Выполнились
Без секретного заголовка 403 Не выполнились
Неверное значение ключа 403 Не выполнились
POST вместо GET 404 в проверенном тесте Это ошибка маршрута, не тест ключа

Шаг 9. Разберите частые несовпадения

Имя заголовка нечувствительно к регистру: x-ezgpt-key с правильным значением в тесте также получил 200. Само значение сравнивается точно: изменение регистра символов ключа привело к 403. Не добавляйте Bearer перед значением, если credential ожидает просто созданную строку.

Authorization: Bearer ... — другой заголовок. Он не заменит X-Ezgpt-Key в этой конфигурации. Ключ в query-параметре тоже не подходит и дополнительно может попасть в историю URL. Используйте только согласованный заголовок, не пробуйте одновременно раскладывать секрет по нескольким полям.

Если корректный на вид запрос получает 403, проверьте, какой credential реально выбран в Webhook, его Name и Value, а также метод и тестовый адрес. Не переключайте Authentication на None для обхода отказа. В отдельном диагностическом workflow редакция подтвердила: с None тот же учебный ответ доступен без ключа.

Шаг 10. Проверьте историю и оставьте схему учебной

Откройте данные успешного выполнения и оцените, где сохраняются входные заголовки. В нашем тестовом экземпляре созданный секрет обнаруживался в данных execution, возвращаемых API. Он не отражался в ответе клиенту, но сохранение в credential не убрало его из истории входящего запроса. Не обещаем, что конкретная настройка n8n автоматически скроет ключ во всех местах.

Используйте отдельный учебный секрет, ограничьте доступ к данным выполнения и настройте хранение и редактирование чувствительных значений по правилам своей системы. Не отправляйте сырые executions в общий чат или внешний AI-сервис. Cache-Control: no-store относится к HTTP-кэшу, а не к базе выполнения n8n.

Верните Authentication: Header Auth и нужный credential. Проверьте ещё раз пару результатов: правильный ключ — 200 с учебным JSON, отсутствующий — 403 без Build Reply. Схему оставьте неопубликованной и остановите тестовое ожидание после работы. Не используйте этот учебный секрет в рабочем сервисе.

Если результат отличается

Симптом Что проверить Действие
403 с вашим ключом Credential, Name и точное Value Сверить обе стороны, не отключать auth
404 Test URL, GET и слушатель Включить ожидание и исправить маршрут
Предупреждение о credentials Выбор после импорта Создать и выбрать свой credential
200 без ключа Authentication и совпадение endpoint Должен быть Header Auth
Ключ есть в execution Доступ, хранение и маскирование Не рассылать сырые данные

Перед production

Один общий секрет не даёт индивидуальных прав пользователям и не подписывает тело запроса. Он не защищает от повторной отправки уже известного запроса. Для реальной интеграции отдельно продумайте HTTPS, хранение и замену ключей, ограничения запросов, проверку прав на действие и защиту от повторов. Не используйте IP-адрес или секретный путь вместо проверки доступа.

Если сервис-отправитель использует HMAC-подпись, OAuth или JWT, применяйте его документированный протокол, а не называйте простой Header Auth равноценной заменой. В этой инструкции проверен один фиксированный заголовок и ответ с вымышленными данными; production, proxy и полный аудит безопасности не выполнялись.

Принять JSON через Webhook

Вернуть файл из Webhook

Что проверено редакцией

17 октября 2026 года схема проверена на n8n 2.42.4 в отдельном Docker-экземпляре реальными запросами к Test Webhook. Все 16 проверок прошли: правильный ключ, имя заголовка строчными буквами, дополнительный несвязанный заголовок; отсутствие ключа, неверное и пустое значение, другое имя заголовка, ключ только в query, только в Bearer, изменённый регистр ключа и неверно выбранный credential. Подтверждены 200 с точным учебным JSON для правильных запросов и 403 без запуска Build Reply для отказов. Проверены 404 без слушателя, при неверном методе, повторе после успешного теста и у неактивного Production URL. Отдельный диагностический workflow с Authentication None подтвердил доступ без ключа. Публичная схема использовалась с привязкой созданных локально credentials; секретов в скачиваемом workflow нет. В данных успешных executions секрет обнаруживался, в ответе клиенту отсутствовал; сохранённые JSON-отчёты очищены от значения. Настройки сверены с официальной документацией и кодом Webhook. Учебный контейнер доступен только на loopback и остановлен, существующие workflows не менялись. Клики редактора, production-публикация, Cloud, proxy, замена рабочего ключа, HMAC/JWT, TLS-конфигурация и полный аудит безопасности не тестировались. Обложка — редакционная AI-иллюстрация с маской вместо ключа, не снимок интерфейса.

Частые вопросы

Почему неправильный ключ даёт 403, а не 401?

В проверенном n8n 2.42.4 эта настройка Webhook вернула 403. Смотрите фактический ответ своего экземпляра и проверяйте, что рабочие узлы не запустились.

Можно передать ключ в ссылке?

Не для описанного Header Auth. Здесь проверяется X-Ezgpt-Key в заголовке. Query-параметр не прошёл тест и может оставить секрет в истории URL.

Почему импортированный workflow просит credentials?

Секрет и ID чужого credential намеренно не включены в публичный JSON. Создайте собственный Header Auth credential и выберите его в Webhook.

Достаточно спрятать URL или настроить CORS?

Нет. Они не заменяют проверку секрета для внешнего HTTP-клиента. В этой инструкции отказ без ключа обеспечивает Header Auth.

Ключ сохранён в credentials: значит, его нет в истории?

Нет такой гарантии. В нашем тесте значение присутствовало в данных успешного execution. Ограничивайте доступ к истории и не пересылайте сырые входные заголовки.

Дальше по теме

Похожие материалы