# 2026-09-20 — Вход через Яндекс ID (web + mobile) ## Запрос Кнопка «Войти через Яндекс» в кабинете и в приложении. Client ID / secret уже заведены в Yandex OAuth. ## Решение Authorization code. Secret только на API (`YANDEX_CLIENT_SECRET` в `.env`, не в web/mobile и не в git). Клиенты получают `client_id` с `GET /api/auth/providers` и шлют `code` + `redirect_uri` в `POST /api/auth/yandex`. API меняет код на токен Яндекса (`oauth.yandex.ru/token`), читает профиль (`login.yandex.ru/info`) и выдаёт тот же JWT, что и Telegram. `users.user_id` для Яндекса: ` (1 << 50) | yandexId ` — не пересекается с Telegram id и остаётся внутри `Number.MAX_SAFE_INTEGER`, чтобы JSON в браузере и Flutter не терял точность. `redirect_uri` сверяется с allowlist (продакшен `https://please-pay-me.ru/`, localhost:51290 и :5173, плюс `YANDEX_REDIRECT_URI` / `YANDEX_REDIRECT_URIS`). ## Потоки - Web: кнопка → `oauth.yandex.ru/authorize` → возврат на `/?code=` (как в кабинете Яндекса) → `RequireAuth` переносит query на `/login` → `loginWithYandex` → `setSession`. - Mobile: своя кнопка → WebView на Яндекс → перехват `{кабинет}/?code=` → `POST /api/auth/yandex` из Flutter. ## Что нужно в консоли Яндекса Redirect URI: `https://please-pay-me.ru/` — как зарегистрировано в Яндексе. ## Секрет Значения записаны в корневой `.env` (gitignore). В репозиторий не коммитятся. Секрет светился в чате — если репозиторий общий, лучше перевыпустить в кабинете Яндекса.