> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# Вход по ключу доступа

Беспарольный вход через передачу в браузер, возвращающую сессию в приложение.

## Как работает передача в браузер

Вход по ключу доступа начинается в приложении и завершается в системном браузере. Приложение открывает {API URL}/auth?mobile_callback=<deep link> через WebBrowser.openAuthSessionAsync; после того как веб-страница завершает любой способ входа, она вызывает GET /api/auth/mobile-handoff, который перенаправляет обратно на <scheme>://auth/callback, перенося сессионную куки и одноразовый nonce состояния.

Каждая попытка генерирует свежий nonce, который должен вернуться без изменений — несовпадающий параметр state отклоняется как stateMismatch, поэтому устаревший или подделанный колбэк не может внедрить сессию. Возвращённая куки сливается в то же хранилище SecureStore, которое использует клиент Better Auth Expo (supastack.auth_cookie), затем хранилище сессии получает уведомление и рендерится приложение для вошедшего пользователя.

Закрытый пользователем браузерный лист разрешается в тихий результат cancelled, а не в ошибку, поэтому при нём оставляйте экран входа без изменений.

```
# apps/mobile/.env.local
EXPO_PUBLIC_APP_SCHEME=supastack

# apps/web/.env.local — server side
AUTH_PASSKEY_ENABLED=true
MOBILE_ALLOWED_ORIGINS=
```


## Держите список разрешённых одинаковым с обеих сторон

Обе стороны проверяют цель колбэка: приложение принимает только <scheme>://auth плюс настроенные production-источники, а сервер проверяет тот же список, построенный из EXPO_PUBLIC_APP_SCHEME и MOBILE_ALLOWED_ORIGINS. Колбэки с учётными данными, неизвестными схемами или похожими суффиксами отклоняются до того, как переместится любая куки.

В production MOBILE_ALLOWED_ORIGINS обязателен и должен перечислять точные нелокальные HTTPS-источники — подстановочные знаки не принимаются. Приложение поставляется в собранном виде, а сервер читает своё окружение при каждом запросе, поэтому смена схемы или источника требует и новой сборки приложения, и развёртывания сервера; изменение только одной стороны заставляет передачи завершаться отказом.


## Остальные беспарольные способы

Тот же экран входа предлагает одноразовые коды по электронной почте (requestEmailOtp, затем verifyEmailOtp) и социальный вход через Apple или Google через signIn.social с callbackURL. Ключи доступа появляются, когда на сервере AUTH_PASSKEY_ENABLED=true; настройка ключей доступа и двухфакторной защиты аккаунта по-прежнему живёт в веб-приложении в разделе «Настройки → Безопасность».


## Проверка и устранение неполадок

Отработайте колбэк холодного старта, возврат в работающее приложение, отменённый браузерный лист и истёкшую сессию на целевой сборке. Типизированные сбои — passkeyUnavailable, browserFailed, untrustedCallback, missingCookie, malformedCookie, cookieStoreFailed — каждый описывает отдельную поломку; stateMismatch означает, что nonce не вернулся и попытка была корректно отклонена.

Если каждая передача отклоняется, сравните EXPO_PUBLIC_APP_SCHEME в поставленной сборке со схемой сервера и MOBILE_ALLOWED_ORIGINS — пара расходится, когда одна сторона была передеплоена без другой.


## Вперёд

[Мобильный API](https://supastack.dev/ru/docs/mobile/api.md)
