> ## 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>；網頁完成任意登入方式後呼叫 GET /api/auth/mobile-handoff，隨即重定向回 <scheme>://auth/callback，並攜帶會話 Cookie 和一個 state nonce。

每次嘗試都會生成一個全新的 nonce，且必須原樣往返 —— state 引數不匹配會被判為 stateMismatch，因此過期或偽造的回撥無法注入會話。返回的 Cookie 會合入 Better Auth Expo 客戶端使用的同一個 SecureStore 儲存（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 構建的同一份列表。攜帶憑據、未知 scheme 或相似字尾的回撥，在任何 Cookie 轉移之前就會被拒絕。

生產環境中 MOBILE_ALLOWED_ORIGINS 為必填，且必須列出精確的非本地 HTTPS 來源 —— 不接受萬用字元。應用以打包形式分發，而伺服器按請求讀取自身環境，因此修改 scheme 或來源必須同時釋出新的應用構建和伺服器部署；只改一側會讓交接以失敗關閉收場。


## 其他免密碼方式

同一個登入介面還提供郵箱一次性驗證碼（先 requestEmailOtp 再 verifyEmailOtp），以及通過 signIn.social 加 callbackURL 的 Apple 或 Google 社交登入。伺服器上 AUTH_PASSKEY_ENABLED=true 時會出現通行金鑰；賬戶的通行金鑰與兩步驗證設定仍在 Web 應用的“設定 → 安全”中。


## 驗證與排障

在目標構建上演練冷啟動回撥、返回執行中的應用、取消的瀏覽器彈層以及過期會話。這些帶型別的失敗 —— passkeyUnavailable、browserFailed、untrustedCallback、missingCookie、malformedCookie、cookieStoreFailed —— 各自對應一種不同的斷點；stateMismatch 表示 nonce 未能往返一致，該嘗試被正確拒絕。

如果所有交接都被拒絕，請對比釋出構建中的 EXPO_PUBLIC_APP_SCHEME 與伺服器的 scheme 和 MOBILE_ALLOWED_ORIGINS —— 一側重新部署而另一側沒有跟進時，這對值就會漂移。


## 下一篇

[移動端 API](https://supastack.dev/zh-tw/docs/mobile/api.md)
