База знаний

Telegram Mini Apps: DeviceStorage и SecureStorage — локальное и защищённое хранилище

В Bot API 9.0 у Telegram Mini Apps появились DeviceStorage и SecureStorage — локальное и защищённое хранилища прямо на устройстве. Разбираем, чем они отличаются от CloudStorage, как ими пользоваться и что туда класть.

Опубликовано

Telegram Mini Apps долго жили без нормального локального хранилища: единственным встроенным вариантом был CloudStorage — облачный, ограниченный по объёму и общий между устройствами. В апреле 2025 в Bot API 9.0 появились сразу два новых хранилища, которые работают на устройстве пользователя: DeviceStorage и SecureStorage. Первое — для обычных данных, второе — для токенов и секретов.

📌
Коротко: DeviceStorage — это persistent локальное хранилище на устройстве, аналог localStorage, но привязанный к конкретному боту, до 5 МБ. SecureStorage — защищённое хранилище поверх iOS Keychain и Android Keystore для sensitive-данных, до 10 элементов. Оба объекта живут на Telegram.WebApp рядом с CloudStorage и доступны с Bot API 9.0.

Что это такое

Это два новых поля у объекта Telegram.WebApp:

  • Telegram.WebApp.DeviceStorage — постоянное локальное хранилище на устройстве, концептуально близкое к window.localStorage в браузере, но изолированное внутри Telegram-клиента. Данные принадлежат конкретному боту и недоступны другим мини-приложениям.
  • Telegram.WebApp.SecureStorage — защищённое локальное хранилище для sensitive-данных. На iOS использует системный Keychain, на Android — Keystore. Всё содержимое шифруется на уровне ОС.

Оба объекта работают на устройстве, а не в облаке. Если пользователь откроет мини-приложение с другого устройства, DeviceStorage и SecureStorage будут пустыми. Для синхронизации между устройствами по-прежнему нужен CloudStorage или собственный backend.

Основные возможности

DeviceStorage

  • setItem(key, value, [callback]) — записать значение по ключу.
  • getItem(key, callback) — прочитать значение.
  • removeItem(key, [callback]) — удалить ключ.
  • clear([callback]) — очистить всё хранилище бота на устройстве.
  • Объём — до 5 МБ на пользователя на одно мини-приложение.
  • Все методы возвращают сам объект DeviceStorage, поэтому их можно чейнить.

SecureStorage

  • setItem(key, value, [callback]) — сохранить секрет.
  • getItem(key, callback) — прочитать секрет. Если ключ удалён, но потенциально восстановим (например, через iCloud Keychain Sync), третий аргумент колбэка — canRestore: true.
  • restoreItem(key, [callback]) — попросить пользователя восстановить ключ через системный диалог.
  • removeItem(key, [callback]) — удалить.
  • clear([callback]) — стереть всё.
  • Лимит — до 10 элементов на пользователя на одно мини-приложение.
⚖️
Trade-off: DeviceStorage оптимален для большого объёма обычных данных — кэш, состояние UI, последний выбранный язык. SecureStorage — крошечный, но защищённый. Не пытайтесь сложить туда весь стейт; он рассчитан именно на токены и секреты.

Подключение и использование

Шаг 1. Подключить Telegram Web App SDK

В HTML мини-приложения добавьте официальный скрипт:

<script src="https://telegram.org/js/telegram-web-app.js"></script>

Объекты DeviceStorage и SecureStorage доступны в window.Telegram.WebApp сразу после загрузки.

Шаг 2. Проверить версию Bot API

Хранилища работают только с Bot API 9.0+ (Telegram-клиент апреля 2025 года и новее). Делайте feature-detection:

const tg = window.Telegram.WebApp

if (tg.isVersionAtLeast("9.0") && tg.DeviceStorage) {
  // безопасно использовать DeviceStorage
} else {
  // фолбэк на localStorage или CloudStorage
}

Шаг 3. Записать и прочитать значение

const storage = window.Telegram.WebApp.DeviceStorage

storage.setItem("ui:theme", "dark", (err, ok) => {
  if (err) return console.error(err)
  console.log("Сохранено:", ok)
})

storage.getItem("ui:theme", (err, value) => {
  if (err) return console.error(err)
  console.log("Тема:", value) // "dark" или null
})

Шаг 4. Хранить токены через SecureStorage

const secure = window.Telegram.WebApp.SecureStorage

secure.setItem("auth:refresh_token", refreshToken, (err, ok) => {
  if (err) return console.error("Не удалось сохранить токен", err)
})

secure.getItem("auth:refresh_token", (err, value, canRestore) => {
  if (err) return
  if (value) {
    bootstrap(value)
  } else if (canRestore) {
    secure.restoreItem("auth:refresh_token", (err, restored) => {
      if (restored) bootstrap(restored)
    })
  } else {
    redirectToLogin()
  }
})
💡
Совет: заведите единый префикс ключей под своё мини-приложение, например app: или feature:. Хотя данные и так изолированы от других ботов, внутри одного приложения это упростит миграции и точечный clear() отдельных подсистем.

Тарифы и лимиты

  • Bot API сам по себе бесплатен: за DeviceStorage и SecureStorage Telegram денег не берёт.
  • DeviceStorage — до 5 МБ суммарно на пользователя для одного мини-приложения. Ограничений по символам в ключах и значениях не задокументировано, но не злоупотребляйте: это всё равно локальный диск пользователя.
  • SecureStorage — до 10 элементов на пользователя для одного мини-приложения. Размер каждого значения отдельно не указан, но это не место для крупных blobs.
  • Версия клиента: только Telegram-клиенты с Bot API 9.0+. На устаревших клиентах объекты могут отсутствовать — всегда проверяйте.
  • CloudStorage остаётся отдельным каналом: до 1024 ключей, значения до 4096 символов, ключи только A-Z a-z 0-9 _ -. Используйте его, когда данные нужны на всех устройствах пользователя.
⚠️
Внимание: SecureStorage не делает приложение «безопасным» автоматически. Это всего лишь правильное место хранения. Логику защиты (ротация refresh-токенов, скоуп ключей, проверка initData на сервере) пишите сами.

Практические сценарии

Кэш и UI-состояние. Тема, выбранный язык, последний открытый раздел, развёрнутые секции — всё это идеально ложится в DeviceStorage. Открывая приложение, вы сразу показываете пользователю «его» интерфейс.

Офлайн-кэш контента. Списки заказов, прайсы, FAQ можно сохранять в DeviceStorage и подтягивать при холодном старте, пока идёт сетевой запрос. Перерисовка интерфейса становится почти мгновенной.

Хранение access/refresh-токенов. SecureStorage заменяет хрупкие схемы, в которых токены жили в localStorage или CloudStorage. Если у вас собственный backend поверх initData, refresh-токен от него имеет смысл класть именно сюда.

Биометрический сценарий. В связке с BiometricManager (Bot API 7.2+) SecureStorage позволяет собрать классический паттерн: пользователь логинится паролем один раз, токен ложится в Secure, на следующих входах разблокировка идёт по Face ID или Touch ID.

A/B и feature flags на устройстве. Бакетирование пользователя удобно зафиксировать в DeviceStorage, чтобы он не «прыгал» между группами при каждом запуске.

Миграция с CloudStorage. Если раньше вы хранили в CloudStorage всё подряд, имеет смысл разделить: пользовательские настройки и кэш — в DeviceStorage, кросс-девайс данные — в CloudStorage, токены и ключи — в SecureStorage.

Ссылки


По теме

Если вы делаете мини-приложение в Telegram и упёрлись в CloudStorage — скорее всего, пора аккуратно перетряхнуть, какие данные у вас на самом деле кросс-девайсные, какие можно держать на устройстве, а какие никогда не должны лежать в обычном хранилище. Хотите обсудить, как разложить это под вашу задачу, — напишите в Telegram, соберём схему вместе.