В веб-картографии аутентификация чаще всего требуется при работе с
приватными слоями, корпоративными геосервисами и платными API, где
доступ к тайлам, векторным данным или WMS/WMTS ресурсам ограничен. В
OpenLayers запросы к данным выполняются через стандартные механизмы
браузера (XHR или fetch), поэтому любые схемы
аутентификации реализуются на уровне HTTP-запросов, конфигурации
источников (source) или кастомных загрузчиков.
Ключевые ограничения, влияющие на архитектуру:
Наиболее универсальный способ аутентификации — добавление заголовков
Authorization или кастомных header-параметров.
В стандартных ol/source/XYZ и
ol/source/TileImage нет прямого параметра headers, но
используется функция tileLoadFunction, позволяющая
полностью контролировать загрузку:
import XYZ from 'ol/source/XYZ';
import TileLayer from 'ol/layer/Tile';
const source = new XYZ({
url: 'https://api.example.com/tiles/{z}/{x}/{y}.png',
tileLoadFunction: (tile, src) => {
const img = tile.getImage();
fetch(src, {
headers: {
Authorization: 'Bearer YOUR_TOKEN'
}
})
.then(res => res.blob())
.then(blob => {
const objectUrl = URL.createObjectURL(blob);
img.src = objectUrl;
});
}
});
const layer = new TileLayer({
source
});
Особенности:
Самый простой, но менее безопасный подход — передача токена через query-параметры.
const source = new XYZ({
url: 'https://api.example.com/tiles/{z}/{x}/{y}.png?token=YOUR_TOKEN'
});
Используется при:
Риски:
Для WMS чаще всего применяется ol/source/ImageWMS или
ol/source/TileWMS.
import ImageWMS from 'ol/source/ImageWMS';
const source = new ImageWMS({
url: 'https://geo.example.com/geoserver/wms',
params: {
'LAYERS': 'workspace:layer',
'TILED': true
},
ratio: 1,
serverType: 'geoserver'
});
Добавление авторизации через headers:
source.setImageLoadFunction((image, src) => {
const img = image.getImage();
fetch(src, {
headers: {
Authorization: 'Basic ' + btoa('user:password')
}
})
.then(r => r.blob())
.then(blob => {
img.src = URL.createObjectURL(blob);
});
});
Особенности WMS:
withCredentials на уровне сервераWMTS чаще работает через шаблоны URL:
import WMTS from 'ol/source/WMTS';
const source = new WMTS({
url: 'https://geo.example.com/wmts?token=YOUR_TOKEN',
layer: 'layer_name',
matrixSet: 'EPSG:3857'
});
При необходимости сложной авторизации используется кастомный
tileLoadFunction, аналогично XYZ.
Если сервер использует сессии (например, после логина через форму),
OpenLayers может автоматически отправлять cookies при включении
credentials.
fetch('https://geo.example.com/session', {
method: 'POST',
credentials: 'include',
body: JSON.stringify({
login: 'user',
password: 'pass'
})
});
Далее все источники используют cookies:
const source = new XYZ({
url: 'https://geo.example.com/tiles/{z}/{x}/{y}.png',
tileLoadFunction: (tile, src) => {
const img = tile.getImage();
fetch(src, {
credentials: 'include'
})
.then(r => r.blob())
.then(blob => {
img.src = URL.createObjectURL(blob);
});
}
});
Особенности:
требует корректной настройки CORS:
Access-Control-Allow-Credentials: true*подходит для корпоративных систем и внутренних порталов
Распространённый подход для публичных API — генерация временно действующих URL с подписью.
function buildSignedUrl(z, x, y) {
const expires = Date.now() + 60 * 1000;
const base = `/tiles/${z}/${x}/${y}.png`;
const signature = md5(base + expires + SECRET_KEY);
return `${base}?expires=${expires}&sig=${signature}`;
}
const source = new XYZ({
url: (z, x, y) => buildSignedUrl(z, x, y)
});
Применяется при:
Преимущество — отсутствие необходимости хранить токен на клиенте в явном виде.
Глобальная модификация запросов позволяет централизовать аутентификацию для всех слоёв.
const originalFetch = window.fetch;
window.fetch = function(url, options = {}) {
const modifiedOptions = {
...options,
headers: {
...(options.headers || {}),
Authorization: 'Bearer YOUR_TOKEN'
}
};
return originalFetch(url, modifiedOptions);
};
Используется в:
Риски:
Vector tiles (ol/source/VectorTile) часто используют
protobuf (MVT) и требуют более аккуратной работы с загрузкой.
import VectorTileSource from 'ol/source/VectorTile';
import MVT from 'ol/format/MVT';
const source = new VectorTileSource({
format: new MVT(),
url: 'https://api.example.com/tiles/{z}/{x}/{y}.pbf',
tileLoadFunction: (tile, src) => {
fetch(src, {
headers: {
Authorization: 'Bearer TOKEN'
}
})
.then(r => r.arrayBuffer())
.then(data => {
tile.setFeatures(
source.getFormat().readFeatures(data, {
extent: tile.getExtent(),
featureProjection: 'EPSG:3857'
})
);
});
}
});
Особенности:
arrayBuffer вместо изображенияВ долгоживущих сессиях токены устаревают, поэтому требуется механизм обновления.
let accessToken = await getAccessToken();
async function authFetch(url, options = {}) {
let res = await fetch(url, {
...options,
headers: {
...(options.headers || {}),
Authorization: `Bearer ${accessToken}`
}
});
if (res.status === 401) {
accessToken = await refreshToken();
res = await fetch(url, {
...options,
headers: {
...(options.headers || {}),
Authorization: `Bearer ${accessToken}`
}
});
}
return res;
}
Интеграция с OpenLayers:
tileLoadFunction: (tile, src) => {
const img = tile.getImage();
authFetch(src)
.then(r => r.blob())
.then(blob => {
img.src = URL.createObjectURL(blob);
});
}
Без корректной настройки CORS любые схемы аутентификации становятся неработоспособными.
Обязательные заголовки сервера:
Access-Control-Allow-OriginAccess-Control-Allow-Headers: AuthorizationAccess-Control-Allow-Methods: GET, OPTIONSПри cookie-аутентификации дополнительно:
Access-Control-Allow-Credentials: trueОсобенности поведения браузера:
OpenLayers активно использует кэширование тайлов, что влияет на безопасность:
Для предотвращения утечек применяются:
В сложных системах OpenLayers редко работает напрямую с секретами. Используются промежуточные слои:
Типичный прокси:
Client → OpenLayers → Backend Proxy → GIS Server
Преимущество:
Недостаток:
В OpenLayers аутентификация всегда реализуется через комбинацию уровней:
fetch,
tileLoadFunction)source configuration)Каждая модель выбирается исходя из баланса между безопасностью, производительностью и сложностью поддержки системы.