Files
please-pay-me/context/2026-09-20_01-20-00_telegram-webview-login.md
T
2026-09-21 04:06:43 +03:00

3.8 KiB
Raw Blame History

2026-09-20 — Вход через WebView + Telegram Login Widget

Запрос

Реализовать нативный вход: открыть кабинет в WebView и забрать JWT через JS-канал. Бэкенд не менять.

Почему не «просто открыть страницу»

Telegram Login Widget в обычном браузере работает через iframe + data-onauth. В Android/iOS WebView этот путь ломается:

  • popup (window.open на oauth.telegram.org) не возвращает opener;
  • iframe режется third-party cookies и User-Agent с маркером ; wv;
  • callback onTelegramAuth просто не вызывается.

Поэтому в WebView виджет переключается на redirect-режим (data-auth-url), а Flutter забирает уже готовый JWT, который кабинет и так кладёт в localStorage.ppm_session_jwt. API (POST /api/auth/telegram) не трогали.

Поток

  1. Экран входа на iOS/Android показывает «Войти через Telegram».
  2. Открывается fullscreen WebView на {cabinet}/login.
  3. Кабинет видит канал window.PpmAuth → ставит виджету data-auth-url=/login.
  4. Пользователь логинится в Telegram; редирект приходит на /login?id&hash&….
  5. telegramPayloadFromQuery собирает payload, кабинет зовёт тот же loginWithTelegram / POST /api/auth/telegram.
  6. setSession пишет JWT в localStorage и зовёт PpmAuth.postMessage.
  7. Flutter парсит сообщение, закрывает WebView, проверяет токен через GET /api/me, кладёт сессию в SharedPreferences.

Запасные пути, если кабинет ещё не задеплоен с мостом:

  • JS в WebView хукает localStorage.setItem('ppm_session_jwt') и поллит ключ;
  • на Windows/web WebView нет — форма «вставить токен»;
  • «Демо-режим» по-прежнему без сети.

Что изменилось

Web (не API)

  • web/src/auth/telegramRedirect.ts — разбор query и postTokenToNativeApp.
  • TelegramLoginButtondata-auth-url только если есть window.PpmAuth.
  • LoginPage — автологин, если в URL уже лежит telegram-payload.
  • setSession — после записи токена шлёт его в канал.

Mobile

  • TelegramLoginScreen (webview_flutter): канал PpmAuth, Chrome UA без ; wv, third-party cookies на Android, tg:// уходит во внешнее приложение, кнопка «назад» после oauth.telegram.org.
  • resolveCabinetLoginUri всегда открывает /login.
  • INTERNET в main AndroidManifest (раньше был только в debug).
  • iOS: LSApplicationQueriesSchemes для tg / telegram.
  • PPM_WEB_URL по умолчанию = PPM_API_BASE_URL (один origin за nginx).

Тесты

  • resolveApiBaseUrl / resolveCabinetLoginUri / парсер канала.
  • виджет: инжектированный launcher отдаёт JWT → GET /api/me → signed in.
  • 32 теста приложения, 102 в Widgetbook, flutter analyze чистый.

Запуск против живого кабинета

cd mobile
.\run.ps1 -Device windows   # на Windows будет форма токена
# на телефоне:
.\run.ps1 -ApiBaseUrl https://<домен-кабинета>

Нужен публичный HTTPS и BotFather /setdomain на этот домен — как для веба.