Аутентификация пользователей

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

В Mapbox GL JS нет встроенной системы пользователей. Библиотека не управляет логинами, сессиями или аккаунтами конечных пользователей. Вместо этого используется модель:

  • Access Token — ключ доступа к API Mapbox
  • Client-side rendering — выполнение запросов из браузера
  • Server-side контроль — управление токенами и доступами на сервере приложения

Access token выступает идентификатором проекта, а не конкретного пользователя. Он определяет:

  • доступ к тайлам (vector/raster tiles)
  • доступ к стилям
  • доступ к геокодированию и другим API Mapbox
  • ограничения по домену и использованию

Подключение токена в Mapbox GL JS

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

import mapboxgl from "mapbox-gl";

mapboxgl.accessToken = "YOUR_PUBLIC_ACCESS_TOKEN";

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

Этот токен считается публичным, но ограниченным настройками безопасности в панели Mapbox.

Разделение публичных и секретных токенов

Система Mapbox использует два основных типа токенов:

Публичный token

Используется в браузере вместе с Mapbox GL JS:

  • безопасен для фронтенда при правильной настройке
  • ограничивается доменами (allowed URLs)
  • имеет ограниченные scopes

Секретный token

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

  • доступ к управлению ресурсами аккаунта
  • создание/удаление токенов
  • управление tilesets и стилями
  • не должен попадать в клиентский код

Критическое правило архитектуры: секретный токен никогда не размещается в браузере.

Ограничение доступа через scopes и правила

В Mapbox можно настраивать ограничения токенов:

  • URL restrictions (например, https://example.com/*)
  • API scopes (styles:read, tiles:read и др.)
  • rate limits
  • временные токены (expiring tokens)

Пример логики ограничения:

  • фронтенд получает только read-only token
  • сервер выдаёт временный token с ограничением по времени
  • обновление токена происходит через backend

Пользовательская аутентификация и Mapbox

Хотя Mapbox GL JS не управляет пользователями напрямую, она часто интегрируется с системами:

  • JWT (JSON Web Token)
  • OAuth 2.0
  • session-based auth (cookies)

Типовая схема:

  1. Пользователь входит в приложение

  2. Backend проверяет учетные данные

  3. Backend выдаёт:

    • пользовательский JWT
    • временный Mapbox token (если требуется)
  4. Frontend использует оба токена:

    • JWT — для бизнес-логики
    • Mapbox token — для карт

Пример клиентской интеграции:

async function initMap() {
  const session = await fetch("/api/session").then(r => r.json());

  mapboxgl.accessToken = session.mapboxToken;

  return new mapboxgl.Map({
    container: "map",
    style: "mapbox://styles/mapbox/light-v11",
    center: session.userLocation,
    zoom: 12
  });
}

Генерация временных токенов на сервере

На backend часто реализуется прокси-слой:

app.get("/api/mapbox-token", (req, res) => {
  const user = req.user;

  const token = generateMapboxToken({
    scopes: ["styles:read", "tiles:read"],
    expiresIn: "1h",
    urlRestrictions: [`https://app.example.com/users/${user.id}/*`]
  });

  res.json({ token });
});

Такая архитектура позволяет:

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

Доступ к приватным стилям и данным

В Mapbox GL JS можно использовать приватные ресурсы:

  • private styles
  • private tilesets
  • datasets

Доступ к ним контролируется токеном. Если токен не имеет нужных прав, карта вернёт ошибку загрузки ресурсов.

Пример:

mapboxgl.accessToken = PRIVATE_TOKEN;

const map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/username/private-style"
});

Безопасное хранение токенов

На клиенте допустимо хранить только публичные токены:

  • переменные окружения (build-time injection)
  • runtime config (server-rendered HTML)
  • защищённые endpoints для выдачи токена

Нежелательные практики:

  • хранение секретного токена в localStorage
  • хардкод токена в фронтенде
  • передача секретного токена через URL

Ротация и обновление токенов

Для систем с пользовательской аутентификацией важно учитывать:

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

Пример обновления:

async function refreshToken() {
  const res = await fetch("/api/mapbox-token");
  const data = await res.json();

  mapboxgl.accessToken = data.token;
}

В долгоживущих SPA можно использовать интервал обновления:

setInterval(refreshToken, 50 * 60 * 1000);

Архитектурная модель интеграции

Типичная схема работы с аутентификацией в приложении с картами:

  • Frontend (Mapbox GL JS)

    • отображение карты
    • использование временного token
  • Backend API

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

    • рендеринг тайлов
    • стили
    • геоданные

Такое разделение обеспечивает:

  • изоляцию секретов
  • контроль доступа на уровне приложения
  • масштабируемость пользовательской модели

Пользовательская персонализация через аутентификацию

На уровне приложения аутентификация позволяет:

  • отображать разные стили карты для разных ролей пользователей
  • ограничивать доступ к слоям данных
  • подгружать персональные геоданные (например, сохранённые точки)

Пример динамического выбора стиля:

function getStyleForUser(user) {
  if (user.role === "admin") {
    return "mapbox://styles/org/admin-style";
  }

  return "mapbox://styles/mapbox/streets-v12";
}

map.setStyle(getStyleForUser(currentUser));

Ограничения модели безопасности

Модель Mapbox GL JS предполагает, что:

  • клиентскому коду нельзя доверять полностью
  • все критичные ограничения должны дублироваться на backend
  • токен — это ключ доступа, а не идентичность пользователя

Поэтому пользовательская аутентификация всегда реализуется вне Mapbox и лишь связывается с его токенами через инфраструктуру приложения