> ## 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

# パスキーサインイン

ブラウザーハンドオフでセッションをアプリに戻す、パスワードレスのサインイン。

## ハンドオフの仕組み

パスキーのサインインはアプリで始まり、システムブラウザーで完了します。アプリは WebBrowser.openAuthSessionAsync を通じて {API URL}/auth?mobile_callback=<deep link> を開き、Web ページがサインイン方法を完了すると GET /api/auth/mobile-handoff が呼び出され、セッション Cookie と state ノンスを載せて <scheme>://auth/callback へリダイレクトで戻ります。

試行ごとに新しいノンスが生成され、往復で変わらず戻る必要があります — state パラメーターが一致しない場合は stateMismatch として拒否されるため、古い、または偽造されたコールバックはセッションを注入できません。返された Cookie は、Better Auth Expo クライアントが使うのと同じ SecureStore の Cookie ジャー(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 と設定済みの本番オリジンだけを受け付け、サーバーは EXPO_PUBLIC_APP_SCHEME と MOBILE_ALLOWED_ORIGINS から構築した同じリストを確認します。資格情報を含むコールバック、不明なスキーム、類似したサフィックスは、Cookie が移動する前に拒否されます。

本番環境では MOBILE_ALLOWED_ORIGINS が必須で、ローカルではない正確な HTTPS オリジンを列挙する必要があります — ワイルドカードは受け付けられません。アプリはバンドル済みで出荷される一方、サーバーはリクエストごとに環境を読むため、スキームやオリジンの変更にはアプリの新しいビルドとサーバーのデプロイの両方が必要です。片側だけを変えると、ハンドオフは閉じた状態で失敗します。


## その他のパスワードレス方式

同じサインイン画面では、メールのワンタイムコード(requestEmailOtp の後に verifyEmailOtp)と、callbackURL を指定した signIn.social による Apple または Google のソーシャルサインインも提供されます。サーバーで AUTH_PASSKEY_ENABLED=true の場合にパスキーが表示されます。アカウントのパスキーと二要素の設定は、引き続き Web アプリの「設定 → セキュリティ」にあります。


## 検証とトラブルシューティング

対象のビルドで、コールドスタートのコールバック、実行中のアプリへの復帰、キャンセルされたブラウザーシート、期限切れのセッションを試してください。型付きの失敗 — passkeyUnavailable、browserFailed、untrustedCallback、missingCookie、malformedCookie、cookieStoreFailed — はそれぞれ異なる断絶を表します。stateMismatch はノンスが往復しなかったこと、つまり試行が正しく拒否されたことを意味します。

すべてのハンドオフが拒否される場合は、出荷したビルドの EXPO_PUBLIC_APP_SCHEME とサーバー側のスキームおよび MOBILE_ALLOWED_ORIGINS を比較してください — 片側だけを再デプロイすると、この組み合わせがずれます。


## 次へ

[モバイル API](https://supastack.dev/ja/docs/mobile/api.md)
