API-ключ во фронтенде: что можно открыть, а что переносить
Секретный API-ключ нельзя надёжно скрыть в JavaScript, который получает браузер пользователя. Его нужно убрать из клиентской сборки и использовать на стороне сервера, а опубликованный секрет заменить. Сначала проверьте назначение значения: некоторые ключи специально предназначены для публичного клиента и требуют другой модели ограничений.
Сначала выясните, какие права даёт значение
Название API key не описывает полномочия. У одного поставщика это идентификатор подключения браузерного компонента, у другого — секрет для чтения документов или выполнения платных запросов. Найдите в официальной документации именно свой тип ключа, допустимое место использования, доступные операции и способы ограничения. Не делайте вывод только по имени переменной, длине строки или слову public, которое выбрал разработчик.
Например, документация Stripe разделяет publishable keys для клиентских компонентов и секретные ключи. Даже restricted key с ограниченными правами там не предназначен для публичного раскрытия. Этот пример показывает различие типов, а не рекомендует платёжного провайдера или подтверждает возможность подключения конкретного бизнеса.
| Значение в приложении | Что проверить у поставщика | Где его использовать | Что проверить в своём проекте |
|---|---|---|---|
| Публичный ключ клиентского компонента | Разрешён ли выпуск в клиентский код и какие права остаются | В браузере, если это прямо предусмотрено | Включены ли нужные ограничения и нет ли рядом секретного ключа |
| Серверный секрет интеграции | Какие данные и операции он открывает | На сервере с контролируемым доступом | Не включён ли в клиентскую сборку, ответы или сообщения об ошибках |
| Ограниченный серверный ключ | Что разрешено, несмотря на ограничения | На сервере, если документация не разрешает публичное использование | Не ошибочно ли ограниченность принята за разрешение публикации |
| Токен текущего пользователя | Кому принадлежит, срок и допустимые операции | По модели авторизации конкретного приложения | Не подменяет ли он общие полномочия всей организации |
Составьте такую карту до изменения кода. Для каждого значения укажите владельца, поставщика и потребителей, не копируя сам секрет в таблицу. Если документация не позволяет уверенно определить тип, попросите разработчика или поставщика подтвердить назначение. До ответа не стоит распространять значение вместе с клиентом просто потому, что существующая сборка уже работает.
Переменная окружения не создаёт тайник в браузере
Файл окружения помогает передавать конфигурацию инструменту сборки, но сам по себе не определяет, что увидит пользователь. В руководстве Vite прямо указано: значения с префиксом VITE_ попадают в клиентский код при сборке. Для секретов документация предлагает серверную часть или соответствующие серверные функции.
Отсюда практический вывод для владельца проекта: просите показать границу исполнения. Значение может начинать путь в закрытом кабинете хостинга, а затем оказаться в опубликованном файле. Проверять нужно итоговую отдаваемую версию и ответы приложения. Название «секрет» в настройках CI не гарантирует, что сборщик не подставил значение в браузерный код.
Переименование переменной, перенос в другой клиентский модуль или усложнение JavaScript не меняет требования: браузер всё равно должен получить данные, которыми пользуется клиентская программа. Мы советуем не принимать обфускацию как исправление опубликованного серверного ключа. Для проекта на другом сборщике нужно проверить его правила отдельно, а не механически переносить соглашения Vite.
Перенос на сервер: три решения вместо одного
Учебный сценарий: посетитель просит сайт подготовить расчёт доставки. Раньше браузер обращался к поставщику с общим секретом компании. После изменения браузер отправляет своему серверу только сведения, нужные для расчёта, а сервер выполняет допустимый запрос к поставщику. Общий секрет остаётся в контролируемой серверной среде и не возвращается посетителю.
Первое решение — какие действия вообще разрешены через этот путь. Для расчёта не нужен универсальный посредник, принимающий произвольный адрес внешнего API и любые команды. Опишите конкретную операцию и допустимые параметры. Мы советуем оформлять её как отдельную бизнес-функцию приложения, чтобы полномочия общего ключа не становились возможностями каждого посетителя.
Второе — кому доступна операция и какие данные он вправе использовать. Наличие серверной функции не заменяет проверку пользователя, организации и принадлежности объекта. Если функция предназначена для публичной формы, отдельно задайте её допустимый результат и ограничения. Нельзя считать запрос разрешённым только потому, что его отправил интерфейс вашего сайта.
Третье — как ограничить расход ресурсов и объём ответа. Установите понятные границы входных данных, частоты и стоимости операции там, где это применимо. Возвращайте клиенту результат задачи, а не целиком служебный ответ с внутренними подробностями. Ошибка поставщика должна помогать поддержке разобраться, но не раскрывать браузеру ключ и конфигурацию сервера.
Как оформить работу разработчику
- Составить перечень значений, которые клиент получает сейчас, и классифицировать их по документации поставщиков. Публичные идентификаторы отделить от серверных секретов.
- Описать разрешённые операции между браузером, своим сервером и внешним API. Для каждой указать пользователя, допустимые данные и ожидаемый ответ.
- Перенести использование секрета в серверную часть и проверить её собственные права доступа. Не оставлять функцию универсальным обходным путём ко всем операциям поставщика.
- Убрать секрет из клиентского кода и собрать новую версию в разрешённом окружении. Проверить итоговые файлы и штатные ответы, включая обработку ошибок.
- Заменить опубликованный секрет у поставщика по поддерживаемой процедуре. Проверить необходимые интеграции и исключить возврат прежнего значения при следующем выпуске.
Если проект пока состоит только из статических файлов, появление серверной операции меняет состав инфраструктуры. Разработчик должен назвать место исполнения, способ доставки конфигурации, ответственного за обновление и правила журналирования. Само выражение «поставим прокси» не описывает эти решения и не даёт критериев приёмки.
Объём такого изменения можно обсудить в рамках разработки веб-приложения. Если клиент уже использует API в нескольких ролях и организациях, полезен аудит API. В задании лучше перечислить конкретные границы доступа, чем просить «спрятать строку» без проверки новой серверной функции.
Что проверить в готовой версии
Попросите проверить тестовую сборку с учебным значением: клиентские файлы, конфигурацию загрузки, штатные сетевые ответы и сообщения при недоступности поставщика. Настоящий секрет не нужно отправлять в общедоступный онлайн-анализатор. Запишите, какие файлы и сценарии проверены: отсутствие значения в одном исходном модуле не описывает весь выпуск.
Для серверного пути проверьте разрешённую операцию с нужной ролью и отказ там, где доступа быть не должно. Отдельно убедитесь, что клиент не может выбрать чужую организацию или получить ненужные поля ответа. Это проверка вашего приложения на согласованном стенде, а не поиск чужих ключей или попытка использовать внешний сервис без разрешения.
После исправления предусмотрите защиту от повторного включения секрета: разделение клиентской и серверной конфигурации, проверку выпуска и правило обращения с диагностическими данными. Материал о токенах и паролях в журналах приложения поможет проверить соседний канал раскрытия. Перенос на сервер не должен просто переместить секрет из JavaScript в доступный посетителю текст ошибки.
Вопросы и ответы
Как скрыть API-ключ в JavaScript?
Серверный секрет нужно убрать из кода, который получает браузер, и использовать на сервере через ограниченную операцию приложения. Переименование и обфускация не превращают доставленное пользователю значение в секрет.
Любой API key во frontend означает утечку?
Нет: некоторые поставщики предусматривают публичные клиентские ключи. Проверьте назначение конкретного типа и его ограничения; серверный ключ с урезанными правами не становится публичным автоматически.
Достаточно ли вынести ключ из frontend в серверный прокси?
Нужно также ограничить доступ к новой функции, допустимые операции и возвращаемые данные. Иначе общий секрет перестанет отображаться, но его возможности могут остаться доступны через неподходящий серверный интерфейс.
Читайте также
Cloudflare BEACON: что открытые замеры скажут о скорости сайта
КомментарииValkey о FakeValkey: что зелёные тесты без сервера не проверят
КомментарииNuxt 4.6: что меняет отдельный API серверного кода
РазработкаПеренос Webflow CMS: почему одного ZIP с кодом недостаточно
КомментарииОткрытые ИИ-модели: свой сервер или облако — что выгоднее бизнесу
ПоддержкаУстаревшая ОС на сервере: обновлять или переносить