Скрытие токенов в production

Архитектура доступа к сервисам Mapbox GL JS строится вокруг access token, который передаётся в клиентский код и используется для загрузки стилей, тайлов и ресурсов. Это создаёт специфическую проблему: любой токен, попавший в браузер, считается потенциально раскрытым.

В production-среде ключевая задача заключается не в «скрытии токена как строки», а в ограничении его возможностей и контроле среды использования.


Типы токенов и их различия

Public access token

Используется в клиентских приложениях:

  • загружает стили карты
  • запрашивает тайлы
  • обращается к базовым API визуализации

Особенность: такой токен не должен считаться секретом, поскольку он неизбежно попадает в браузер.


Secret token

Используется на серверной стороне:

  • генерация временных токенов
  • управление аккаунтом и биллингом
  • доступ к административным API

Ключевая характеристика: никогда не должен попадать в frontend-бандл


Основная ошибка production-интеграции

Типичный анти-паттерн:

mapboxgl.accessToken = "pk.eyJ1Ijo....";

или хранение в открытом репозитории:

export const MAPBOX_TOKEN = "pk.eyJ1Ijo....";

Такая практика приводит к:

  • бесконтрольному использованию токена
  • возможному злоупотреблению квотами
  • подмене токена в публичных сборках
  • анализу трафика и извлечению ключа из бандла

Ограничение токена через настройки безопасности

Основной механизм защиты — token restrictions в панели Mapbox.

Ограничения по доменам

Токен привязывается к:

  • конкретным доменам
  • поддоменам (например, app.example.com)
  • localhost для разработки

Пример логики:

  • production: https://example.com/*
  • staging: https://staging.example.com/*

Ограничение API scope

Токен может быть ограничен:

  • только Map tiles
  • только Styles API
  • исключение admin API

Это минимизирует ущерб при компрометации.


Управление токеном через переменные окружения

Frontend build-time env

В современных сборщиках токены подставляются на этапе сборки.

Vite

mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_TOKEN;

Webpack

new webpack.DefinePlugin({
  "process.env.MAPBOX_TOKEN": JSON.stringify(process.env.MAPBOX_TOKEN)
});

Next.js

mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN;

Ключевой момент:

  • переменные с префиксом NEXT_PUBLIC_ / VITE_ становятся публичными
  • секретные значения туда не помещаются

Серверный прокси как слой защиты

Один из наиболее надёжных подходов — проксификация запросов к Mapbox API.

Архитектура

Browser → Backend → Mapbox API

Преимущества

  • токен хранится только на сервере
  • контроль rate limiting
  • логирование запросов
  • возможность кэширования тайлов

Пример прокси

app.get("/tiles/:z/:x/:y", async (req, res) => {
  const { z, x, y } = req.params;

  const url = `https://api.mapbox.com/v4/mapbox.satellite/${z}/${x}/${y}.png?access_token=${process.env.MAPBOX_SECRET}`;

  const response = await fetch(url);
  const buffer = await response.arrayBuffer();

  res.set("Content-Type", "image/png");
  res.send(Buffer.from(buffer));
});

Защита через временные токены

Дополнительный уровень безопасности — short-lived tokens.

Механизм:

  1. frontend запрашивает токен у backend
  2. backend генерирует временный ключ
  3. ключ действует ограниченное время

Преимущества:

  • минимизация риска утечки
  • автоматическое истечение
  • контроль сессий пользователей

Ограничение через referrer policy

Даже публичный токен можно защитить от злоупотребления:

  • разрешён только определённый Referer
  • блокировка запросов с неизвестных источников

Это настраивается в панели управления токенами.


Изоляция токена на уровне сборки

.env стратегия

MAPBOX_TOKEN=pk.eyJ1...

и исключение из git:

.env
.env.production

Важно, чтобы:

  • .env никогда не попадал в репозиторий
  • использовался .env.example без значений

Утечка токена через клиентский бандл

Даже при использовании env-переменных токен остаётся доступным в браузере.

Пример:

  • открытие DevTools
  • просмотр Network
  • анализ JS bundle

Следовательно:

скрыть токен полностью невозможно — можно только ограничить его влияние


Дополнительные меры защиты

1. Разделение токенов по средам

  • development token
  • staging token
  • production token

Каждый с разными ограничениями.


2. Ротация токенов

Регулярная смена ключей:

  • при релизах
  • при подозрении на утечку
  • по расписанию

3. Мониторинг использования

Отслеживание:

  • количества запросов
  • географии использования
  • аномальных всплесков

4. Минимизация прав

Токен должен иметь только:

  • доступ к Map rendering API
  • запрет на admin endpoints
  • ограничение на usage scopes

Клиентская интеграция без утечек логики

Пример безопасной и типовой инициализации:

import mapboxgl from "mapbox-gl";

mapboxgl.accessToken = process.env.MAPBOX_TOKEN;

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/streets-v12",
  center: [30.3351, 50.4501],
  zoom: 10
});

Ключевая идея:

  • токен не «прячется»
  • токен ограничивается инфраструктурно

Ошибки, приводящие к компрометации

  • хранение токена в публичном GitHub репозитории
  • отсутствие domain restrictions
  • использование одного токена для всех окружений
  • отсутствие мониторинга usage
  • прямое использование secret token в frontend

Принцип безопасной модели

Работа с Mapbox GL JS в production всегда строится вокруг трёх уровней:

  • ограничение токена
  • изоляция среды
  • контроль инфраструктурного доступа

Любая попытка «полностью скрыть токен» противоречит модели работы браузерных картографических SDK и заменяется системами контроля доступа и мониторинга.