@criipto/verify-expo

中文文档
4.0.3发布于 2026/10/22MITES Module构建来源已验证近 30 天下载 4867

Accept MitID, NemID, Swedish BankID, Norwegian BankID and more logins in your Expo (React-Native) app

原始使用文档
文档目录7 节
  1. Requirements
  2. Installation
  3. Initialization
  4. Getting Started
  5. Warming up
  6. Ephemeral sessions (iOS only)
  7. Idura

criipto-verify-expo

The Idura Verify Expo SDK allows your users to authenticate with a host of European eID providers. It allows your application to act as a public client, meaning it does not use a client secret, but instead employs PKCE to ensure that a malicious actor cannot intercept the authorization code.

In addition to the basic OIDC flow, the SDK also supports app switching.

Requirements

  • Expo SDK 54 or newer (ships React Native 0.81 / Kotlin 2.1.20 / AGP 8.11).
  • Android minSdkVersion 26 or newer. Expo's prebuild default is 24, so you must opt in explicitly via expo-build-properties — see Installation.
  • iOS 17.4 or newer, with use_frameworks! :linkage => :dynamic. The Idura Verify iOS SDK is distributed as a Swift Package, which requires dynamic framework linkage. The Expo plugin verifies both via expo-build-properties.
  • This module includes native code, so it will not work with Expo Go. You must use a build, for instance npx expo run:ios / npx expo run:android or EAS Build.

Both platforms delegate to the native Idura Verify SDKs (Android, iOS). Consumers on older Expo releases should stay on @criipto/verify-expo 3.x.

Installation

npm install @criipto/verify-expo expo-build-properties

Initialization

The SDK needs to be configured with two pieces of information:

  • Your Idura domain.
  • Your Idura client ID.

The SDK assumes that:

  • You will be using your Idura domain to host your redirect URL (both custom domains, *.criipto.id, and *.idura.broker domains can be used).
  • Your redirect URL will be https://[YOUR IDURA DOMAIN]/[ios|android]/callback. Currently, custom redirect URLs are not supported. Open an issue if you need it.

You should register the callback URLs in the Idura dashboard. If your domain is https://samples.criipto.id, you should register both https://samples.criipto.id/ios/callback and https://samples.criipto.id/android/callback.

Then configure both plugins in app.json. expo-build-properties must appear before @criipto/verify-expo so its overrides are applied first:

"plugins": [
  ["expo-build-properties", {
    "android": { "minSdkVersion": 26 },
    "ios": { "useFrameworks": "dynamic", "deploymentTarget": "17.4" }
  }],
  ["@criipto/verify-expo", {
    "domain": "YOUR_IDURA_DOMAIN",
    "clientID": "urn:my:application:identifier:XXXX"
  }]
]

The plugin fails expo prebuild with copy-paste-friendly errors if any of these requirements are unmet.

Getting Started

Call login() directly — there's no provider or hook to wire up. Configuration (domain, clientID) lives in app.json and is read by the native modules. Hold the result in your own state (useState, zustand, react-query — your call) since the package doesn't keep one for you:

// src/LoginButton.jsx
import { useState } from "react";
import { Button, Text } from "react-native";
import { login, OAuth2Error, UserCancelledError } from "@criipto/verify-expo";

export default function LoginButton() {
  const [claims, setClaims] = useState(null);
  const [error, setError] = useState(null);

  const handlePress = async (acrValues) => {
    try {
      const { id_token, trace_id, claims } = await login({ acrValues });
      setClaims(claims);
      setError(null);
    } catch (e) {
      if (e instanceof UserCancelledError) return; // expected; not an error condition
      setError(e);
      setClaims(null);
    }
  };

  return (
    <>
      <Button
        onPress={() => handlePress("urn:grn:authn:dk:mitid:substantial")}
        title="Login with Danish MitID"
      />
      <Button
        onPress={() => handlePress("urn:grn:authn:se:bankid:same-device")}
        title="Login with Swedish BankID"
      />
      <Button onPress={() => handlePress("urn:grn:authn:se:frejaid")} title="Login with Freja ID" />
      <Button
        onPress={() => handlePress("urn:grn:authn:no:bankid:substantial")}
        title="Login with Norwegian BankID"
      />

      {error ? <Text>An error occurred: {error.toString()}</Text> : null}
      {claims ? <Text>{JSON.stringify(claims, null, 2)}</Text> : null}
    </>
  );
}

On failure login() throws a typed error: UserCancelledError for the user dismissing the flow, OAuth2Error for IdP errors, NoSuitableBrowserError (Android-only) when no Custom Tab-capable browser is installed, plus ModuleNotConfiguredError / UnknownPromptError / IduraVerifyInternalError. All carry the SDK's trace_id where available, for correlation in the Idura dashboard.

Warming up

The native SDK is built on the first login() call, which is when OIDC discovery, the JWKS fetch and — on Android — the scan for a usable browser happen. To take that off the login path, call warmUp() from an effect on the screen that logs in:

import { useEffect } from "react";
import { warmUp } from "@criipto/verify-expo";

useEffect(() => {
  warmUp();
}, []);

It is entirely optional, never throws, and is cheap to call more than once. Because it reports nothing, a misconfigured app still fails at login() with ModuleNotConfiguredError — the native side logs the reason under the CriiptoVerifyExpo tag (logcat) or via NSLog, so you can see it while wiring up an integration.

Ephemeral sessions (iOS only)

The web view used to display the login page lets you choose between an ephemeral or a shared browser session.

  • An ephemeral session shares no cookies with the user's default browser, so the user may have to enter their login details. This is the default.
  • A shared session shares cookies with the user's default browser, so login details may be remembered between logins. However, the system presents a permission dialog ("'Your App' wants to use 'idura.broker' to sign in") each time the user logs in.

The default value is to use an ephemeral session.

It is up to you to decide which flow is better, based on the UX requirements of your application. Not all eIDs require the user to enter anything in the webview — for example, Swedish BankID takes the user directly to their authenticator app. For this reason, you may also want to use a shared session for some eIDs but not others. Pass preferEphemeralSession on the login() call to override per-flow:

await login({
  acrValues: "urn:grn:authn:dk:mitid:substantial",
  preferEphemeralSession: false, // opt into a shared browser session
});

Danish MitID supports a re-authentication flow, so you do not need to rely on a shared browser session if you need to re-authenticate the user with MitID.

On Android the parameter is silently ignored: Custom Tab sessions don't share cookies with the browser, and the Android SDK doesn't expose the choice.

Idura

Learn more about Idura and sign up for your free developer account at idura.eu.

版本与发布记录

@criipto/verify-expo 共发布 26 个版本,首次发布于 2023/07/17;过去 12 个月发布了 10 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.0.3latest2026/10/2219 天前
4.0.3-0beta2026/10/2120 天前
4.0.22026/09/072 个月前
4.0.12026/08/252 个月前
4.0.02026/07/024 个月前
4.0.0-22026/06/025 个月前

关于 @criipto/verify-expo 的常见问题

@criipto/verify-expo 是什么?

Accept MitID, NemID, Swedish BankID, Norwegian BankID and more logins in your Expo (React-Native) app

如何安装 @criipto/verify-expo?

在项目目录运行 npm install @criipto/verify-expo,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:expo(>=54)、react(>=19)、react-native(>=0.81)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@criipto/verify-expo 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/criipto__verify-expo 是否存在。

@criipto/verify-expo 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@criipto/verify-expo 可以商用吗?

@criipto/verify-expo 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@criipto/verify-expo 的下载量有多少?

根据 npm 官方下载统计,@criipto/verify-expo 在 2026/10/11 – 2026/11/09 这 30 天内被下载 4,867 次,日均约 162 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@criipto/verify-expo 还在维护吗?

最新版本 4.0.3 发布于 2026/10/22(19 天前);至今共发布 26 个版本,其中过去 12 个月发布了 10 个;首次发布于 2023/07/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。