Design: @ory/elements-native — flow-driven React Native components for Kratos native flows
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 25/100
- Issue 类型
- 功能
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- react, react-native, typescript
- 领域
- authentication, mobile
调研方向
Read the proposed API and package layout in the issue, then review the prototype at kaleabcodes/elements on branch feat/elements-native. Start with @ory/elements-native and examples/react-native, including their unit tests and API report. Done means maintainers agree on the package approach and the proposed native flows and Expo example are implemented; the issue reports that the prototype's checks pass locally.
由索引模型根据 Issue 内容生成。
描述
Preflight checklist
- I could not find a solution in the existing issues, docs, nor discussions.
- I agree to follow this project's Code of Conduct.
- I have read and am following this repository's Contribution Guidelines.
- I have joined the Ory Community Slack.
- I am signed up to the Ory Security Patch Newsletter.
Ory Network Project
No response
Context and scope
Ory Elements renders Kratos self-service flows from flow.ui.nodes for the web
(@ory/elements-react, @ory/nextjs), but there is no equivalent for React
Native. Mobile teams on Ory currently hand-build every login, registration,
recovery and settings screen, and have to rediscover the native-flow details
themselves: session tokens instead of cookies, continue_with handling, AAL2
step-up, and OIDC through a system browser.
This proposes a new package, @ory/elements-native, that brings the same
node-driven approach to React Native using Kratos native (API) flows, plus an
Expo example app in examples/react-native.
I have a working prototype on a fork and would like to align on the approach
before opening a pull request, per the contributing guidelines:
https://github.com/kaleabcodes/elements/tree/feat/elements-native
Goals and non-goals
Goals
- Render login, registration, recovery, verification and settings flows from
flow.ui.nodes, so enabling a method in Kratos changes the app with no code change. - Use only native (API) flows: session tokens, never cookies.
- Headless rendering: the library decides which nodes to show and in what order;
the app supplies its own components (no styling or design system shipped). - Cover the flows a real app needs: password and code login, sign-up,
verification, recovery, profile and password settings, TOTP, lookup secrets,
social sign-in (OIDC), AAL2 step-up and session management.
Non-goals (for a first version)
- Passkeys / WebAuthn. In my testing on Kratos v25.4.0, submitting
method=passkeyormethod=webauthnto a native settings flow returns 400
("Could not find a strategy to update your settings"), so these groups are
shown through an explicitUnsupportedcomponent rather than silently dropped. - Shipping default UI components or themes.
- Web support (the existing web packages already cover that).
The design
Three layers, mirroring @ory/elements-react where it makes sense:
-
Client —
createOryNativeClient(sdkUrl)wraps the KratosFrontendApiand
only callscreateNative*Flow. It maps Kratos responses to a small result
union: success, updated flow (validation errors or the next step, such as
"code sent"), redirect (OIDC), verify, recovered, AAL2 required, expired, failed. -
Context —
OryFlowProviderowns the current flow, submission state and
errors. The app injects platform pieces as props: a token store (e.g.
expo-secure-store), anopenAuthSessionfunction for OIDC (e.g.
expo-web-browser), and lifecycle callbacks (onSuccess,onRegistered,
onVerificationRequired,onAal2Required,onRecovered). -
Rendering —
FlowForm,NodeRenderer,FlowMessagesandSocialButtons
turn nodes into the app's components. Submit nodes become buttons whose values
are sent only when pressed (otherwiseresendrides along on every submit).
Two native-specific problems the design handles:
- Cookies: React Native defaults
withCredentialsto true, so the platform
cookie jar replaysory_kratos_continuityfrom an OIDC round trip and Kratos
then rejects every API submit with "the request was made by a Browser". The
client uses its own HTTP instance with credentials disabled. - Intermediate steps: a 200 response carrying the next flow (recovery "code
sent", registration credential choice) is rendered as the next step instead of
being treated as an error.
APIs
const ory = createOryNativeClient("https://<kratos-public-url>")
// app-supplied components (headless contract)
const components: OryNativeComponents = {
Input, Checkbox, Button, Text, Image, Messages, Group,
Unsupported, // required: unknown nodes stay visible
}
<OryComponentProvider components={components}>
<OryFlowProvider
client={ory}
flowType="login"
tokenStore={tokenStore}
openAuthSession={openAuthSession}
onSuccess={() => router.replace("/home")}
>
<SocialButtons labels={{ google: "Continue with Google" }} />
<FlowForm groups={["password", "code"]} submitLabel="Sign in" />
</OryFlowProvider>
</OryComponentProvider>
Also exported: session helpers (sessionState, whoami, signOut,
listSessions, revokeSession, revokeOtherSessions), verification helpers,
and node utilities (sortNodes, availableGroups, isMfaGroup, ...).
Data storage
The library stores nothing itself. The session token is persisted through an
app-supplied OryTokenStore (get / set / clear); the example uses the
platform secure store (expo-secure-store), never AsyncStorage.
Code and pseudo-code
Prototype: https://github.com/kaleabcodes/elements/tree/feat/elements-native
packages/elements-native: package, unit tests, API report (api-extractor),
changeset. Built with tsup like the other packages.examples/react-native: Expo SDK 57 / React Native 0.86 example covering
sign-up, login, verification, recovery, settings, TOTP, backup codes and
sessions. It is excluded from the pnpm workspace because Expo pins its own
React version, which the rootreactoverride would replace.
The repository's PR checks (pnpm install --frozen-lockfile, then
nx run-many --all -t lint test build api-extractor) pass locally on the branch.
Degree of constraint
- Peer dependencies:
react >= 18,react-native >= 0.74. - Uses
@ory/kratos-client(axios).@ory/elements-reactuses
@ory/client-fetch; I'm happy to switch for consistency — see below. - Expo is used only in the example; the package itself has no Expo dependency.
Alternatives considered
- Browser flows in a WebView: simpler to start, but cookies, CSRF and
WebView-specific auth issues make it a poor fit for native apps, and it is not
what Kratos recommends for native clients. - Reusing
@ory/elements-reactcomponents: they render DOM elements and depend
on web-only APIs, so they cannot run in React Native. @ory/client-fetchinstead of@ory/kratos-client: would match
@ory/elements-reactand drop axios. The cookie fix maps directly to
credentials: "omit". I would follow the maintainers' preference here.
Questions for maintainers
- Is a React Native package something you would accept in this repository?
- Should it live as
packages/elements-native, or under a different name? - Preference between
@ory/client-fetchand@ory/kratos-client?
AI assistance: I used Claude (Anthropic) as a coding assistant while building
the prototype, for much of the implementation, tests and debugging. I set the
requirements and direction, reviewed the changes, and tested the flows on a
physical Android device against a self-hosted Kratos.
- 主要语言
- TypeScript
- 星标
- 188
- 派生
- 80
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
ory/elements 的其他 Issue
-
Needs Triage
难度 2/5 1-3 小时 新手友好度 70/100
-
Needs Triage
难度 5/5 一周以上 新手友好度 22/100
-
enhancement
难度 3/5 1-2 天 新手友好度 72/100
-
good first issue help wanted upstream
难度 2/5 1-3 小时 新手友好度 45/100
-
good first issue help wanted upstream
难度 3/5 1-2 天 新手友好度 25/100
相似的 Issue
-
category::task code priority::normal
难度 2/5 1-3 小时 新手友好度 78/100
e0ipso/strikethroo#145 ·
维护者通常 1 天内回复
-
难度 1/5 1-3 小时 新手友好度 85/100
cocos/cocos-docs#3333 ·
-
bug
难度 2/5 1-3 小时 新手友好度 75/100
RevenueCat/react-native-purchases#2079 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 78/100
RevenueCat/purchases-hybrid-common#2039 ·
维护者通常 1 天内回复
-
agent-reported area/react bug
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复