3.8 KiB
3.8 KiB
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) не трогали.
Поток
- Экран входа на iOS/Android показывает «Войти через Telegram».
- Открывается fullscreen WebView на
{cabinet}/login. - Кабинет видит канал
window.PpmAuth→ ставит виджетуdata-auth-url=/login. - Пользователь логинится в Telegram; редирект приходит на
/login?id&hash&…. telegramPayloadFromQueryсобирает payload, кабинет зовёт тот жеloginWithTelegram/POST /api/auth/telegram.setSessionпишет JWT вlocalStorageи зовётPpmAuth.postMessage.- 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.TelegramLoginButton—data-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в mainAndroidManifest(раньше был только в 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 на этот домен — как для веба.