For AI agents: fetch the complete documentation index at /llms.txt, the full documentation corpus at /llms-full.txt, the agent skill at /skill.md, or this page as Markdown at /zh-tw/docs/mobile/passkeys.md (or send Accept: text/markdown).
通行金鑰登入
通過瀏覽器交接完成免密碼登入,並把會話帶回應用。
交接流程如何運作
通行金鑰登入在應用中發起、在系統瀏覽器中完成。應用通過 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 —— 一側重新部署而另一側沒有跟進時,這對值就會漂移。