38 lines
2.0 KiB
Markdown
38 lines
2.0 KiB
Markdown
# 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). В репозиторий не коммитятся.
|
||
Секрет светился в чате — если репозиторий общий, лучше перевыпустить в
|
||
кабинете Яндекса.
|