移动/游戏
在 Expo/React Native 应用中接入…
为 Expo/React Native 项目用 @clerk/expo 实现认证、会话与路由保护时,按意图选择预构建组件或自定义流程并逐步验证。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Expo/React Native 特定
解决思路
- 确认项目类型为 Expo/React Native(检查 app.json / app.config.js、package.json 中的 expo、metro.config.js、@clerk/expo 依赖),再按 Intent Map 与 Default Path 选择实现路径。
- 按用户意图加载参考文件,只加载任务需要的:Add auth / add sign-in with Clerk → 预构建原生组件(默认):references/setup.md + references/prebuilt-components.md。
- Add auth 但要求 Expo Go / web / 自定义 UI → 自定义流程:references/setup.md + references/custom-flows.md。
- Add phone / SMS auth、email OTP、passwordless → 自定义流程,使用 phoneCode / emailCode:references/custom-flows.md。
- Sign in with Google/Apple/GitHub、social login、SSO → Browser SSO 或原生按钮:references/sso-and-native-auth.md。
- MFA / 2FA / TOTP、forgot password、email link → 自定义流程补充:references/custom-flows.md。
- Protect routes/screens、redirect if signed out → Expo Router guards:references/protected-routes.md。
- Show user profile、org switching、push notifications、sign out、call my backend → App recipes:references/recipes.md。
- Biometric login、Face ID、passkeys → Device features:references/recipes.md。
- 用户说 Add auth 但未指定 UI 时,默认使用预构建原生组件 AuthView + UserButton(来自 @clerk/expo/native);告诉开发者它们处于 beta 且需要 development build。
- 当项目必须在 Expo Go 中运行(无 dev build)、目标为 web(原生组件在 web 不渲染)、或开发者想要自己的 UI/超出主题化的品牌体验时,回退到自定义流程;切换时说明原因。
- 如果开发者已有认证 UI,基于现有实现扩展;未经要求不要移除自定义流程来插入 AuthView(或反向操作)。
- 不要在同一步认证中混合预构建组件与自定义流程(例如 AuthView 加自定义密码表单);只有开发者明确要求时才可混合。
- 按 Quick Workflow 执行:确认项目类型并按 Intent Map / Default Path 选路径。
- 遵循 references/setup.md:安装、环境变量 key、provider、token cache、config plugin、build type。
- 验证 dashboard 前置条件(Gate 2 和 Gate 3)。
- 只根据选定的 reference 实现。
- 通过构建验证,而不只是写代码:运行项目 typecheck(npx tsc --noEmit 或等价命令)。
- 构建并启动:原生功能用 npx expo run:ios / npx expo run:android,Expo Go 流程用 npx expo start;如果构建失败,修复并重新构建迭代——针对已安装 SDK 的构建错误是本技能与 SDK 不一致时的最终依据;约 5 次修复失败后停止并询问开发者,而不是反复折腾。
- 带开发者走一次真实登录,然后确认 session 在 app 重启后仍然存在(token cache 生效)。
- Gate 1 Publishable key:从 process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY(.env 文件)读取;绝不用 NEXT_PUBLIC_,绝不硬编码;如果不存在 key,向开发者索要(或运行 npx clerk@latest init --framework expo,安装 SDK 并写入 env 文件),并在编辑文件前等待。
- Gate 2 Native API dashboard toggle:必须在 Clerk Dashboard → Native applications(https://dashboard.clerk.com/~/native-applications)为 instance 启用 Clerk Native API;setup 时让开发者验证,它是任何原生集成必需。
- Gate 3 Factor availability:实现特定策略(SMS、email code、social provider)前确认该 factor 已为 instance 启用;从 publishable key 派生 Frontend API URL(base64-decode 中间段)并 fetch <frontendApiUrl>/v1/environment?_is_native=true,或让开发者检查 dashboard(User & authentication);SMS 尤其依赖 instance 配置,为禁用 factor 写的代码会在运行时而非构建时失败。
- Gate 4 Current custom-flows API only:来自 @clerk/expo 的 useSignIn() / useSignUp()(v3.4+)返回 { signIn, errors, fetchStatus } 并使用基于方法的流程:signIn.password()、signIn.phoneCode.sendCode()、signIn.finalize()。绝不要生成 legacy pattern:从 useSignIn()/useSignUp() 解构 isLoaded/setActive(当前 hooks 不返回它们),或 signIn.create() 链式调用 prepareFirstFactor()/attemptFirstFactor() + setActive({ session });该模式位于 @clerk/expo/legacy,只用于维护现有 legacy 代码,绝不用于新工作。范围说明:useAuth()/useUser() 的 isLoaded 是当前 API 且在 guards 中必需;signIn.create() 本身对高级场景仍存在——优先使用 factor-specific methods。
- Gate 5 useSSO(), never useOAuth():useOAuth 已 deprecated。注意不对称:startSSOFlow() 仍返回 { createdSessionId, setActive } 且需要 setActive({ session: createdSessionId });SSO 不使用 finalize()。
- Gate 6 Token cache:在 ClerkProvider 上使用来自 @clerk/expo/token-cache 的 tokenCache;绝不要直接用 expo-secure-store 存 session token,绝不用 AsyncStorage。
- Gate 7 resourceCache, never secureStore:如果涉及离线资源缓存,@clerk/expo/secure-store 已 deprecated;使用来自 @clerk/expo/resource-cache 的 resourceCache。
- Gate 8 Build-type gating:原生组件(@clerk/expo/native)和原生 hooks(useSignInWithGoogle、useSignInWithApple、useLocalCredentials)需要 development build(npx expo run:ios / npx expo run:android),不能用 Expo Go,且 web 上不存在;web 目标使用 @clerk/expo/web 组件或自定义流程;实现 native-only 功能前说明构建要求。
- Gate 9 Combined sign-in-or-up default:默认一个合并的登录或注册流程,除非开发者要求分开的 sign-in 和 sign-up 屏幕。
- Gate 10 Bot protection:自定义 sign-up 屏幕必须渲染 <View nativeID="clerk-captcha" />;Clerk 的 bot protection 默认开启且需要这个 mount point。
- Gate 11 Source verification for volatile surfaces:使用原生组件 props 或原生 hook options 前,对照已安装包确认:node_modules/@clerk/expo/dist/native/*.d.ts 和 package.json exports;如果它们与本技能不一致,已安装版本优先。
- Gate 12 Freshness gate:本技能针对 @clerk/expo 3.6.x 验证过。检查已安装版本(node_modules/@clerk/expo/package.json);如果是更新的 minor 或 major,把本技能代码片段视为可疑:使用前根据每个片段旁的 docs URL 或已安装 .d.ts 重新验证;如果低于 3.4,method-based custom-flows API 可能不存在——提供升级而不是写 legacy 代码。
- Version Note:v3.5.0 起最低 React Native 提升到 0.75(iOS SDK 现在通过 SPM podspec 链接);peer range:expo >=53 <57。
- Version Note:原生组件已成熟:iOS 迁移到 Expo Modules;native↔JS session 同步是自动且双向的——native-component auth 后绝不要调用 setActive()。
- Version Note:config plugin 接受一个 theme JSON 文件用于原生组件样式(见 references/prebuilt-components.md)。
- Version Note:Native Google sign-in 将在下个 major 迁移到单独的 @clerk/expo-google-signin 包(@clerk/expo/google import 在 v3 仍可用,dev warning 会宣布迁移);不要在 v3 上预安装新包。
- Pitfall CRITICAL:生成 legacy custom-flow code(signIn.create + prepareFirstFactor + setActive)→ 使用当前 method-based API(Gate 4)。
- Pitfall CRITICAL:使用 useOAuth() → 使用 useSSO()(Gate 5)。
- Pitfall CRITICAL:未检查 factor 已启用就实现 SMS/social auth → 先检查 environment/dashboard(Gate 3)。
- Pitfall CRITICAL:原生组件用于 Expo Go 或 web → 需要 dev build;否则提供自定义流程(Gate 8)。
- Pitfall CRITICAL:sign-up 屏幕缺少 <View nativeID="clerk-captcha" /> → 始终包含它(Gate 10)。
- Pitfall HIGH:使用 NEXT_PUBLIC_ env prefix,或在 node_modules 内读取 env var → 使用 EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY,并显式传给 ClerkProvider。
- Pitfall HIGH:重启后 session 丢失 → 在 provider 上使用来自 @clerk/expo/token-cache 的 tokenCache。
- Pitfall HIGH:在 AuthView / UserButton auth 后调用 setActive() → 原生组件会自动同步 session。
- Pitfall HIGH:把 AuthView 与 useSignInWithGoogle/useSignInWithApple 配对 → AuthView 自身会渲染已启用的 social providers。
- Pitfall HIGH:手动调用 WebBrowser.maybeCompleteAuthSession() → ClerkProvider 会处理它。
- Pitfall HIGH:未经要求拆分 sign-in / sign-up → 默认合并流程(Gate 9)。
- Pitfall MEDIUM:guards 中在 isSignedIn 前缺少 isLoaded 检查 → 始终先以 isLoaded 做门控。
- Pitfall MEDIUM:用 yalc/pnpm link 进行本地 @clerk/expo 开发 → 使用 Verdaccio 或 pkg.pr.new。
- See Also:相关技能 clerk、clerk-swift / clerk-android、clerk-orgs、clerk-billing、clerk-webhooks(hooks 在 Expo 中行为相同)。
- See Also:已安装包源码:node_modules/@clerk/expo/。
- See Also:文档:https://clerk.com/docs/getting-started/quickstart(Expo SDK tab)和 https://clerk.com/docs/reference/expo/overview;示例:https://github.com/clerk/clerk-expo-quickstart(三个官方示例 app:JS-only(Expo Go)、JS + native sign-in buttons、native components)。
适用边界 · 注意事项
- 原生 iOS/Swift 项目(.xcodeproj、Package.swift)→ 用 clerk-swift。
- 原生 Android/Kotlin 项目(无 React Native 的 build.gradle)→ 用 clerk-android。
- 纯 Web 框架(Next.js、Remix、plain React 等)→ 用对应框架技能。