Ionic SDK¶
在本文中,您将学习如何在 Ionic 项目中通过 Authany Ionic SDK 使用 Authany。
说明
本教程的示例应用完整代码可以在这个 Github 仓库中找到。
根据 Capacitor v7 的要求,以下是您的原生应用可以支持的 Android 和 iOS 最低版本:
- iOS 14
- Android 6(API 级别 23)
Objectives (What we'll build)¶
完成本教程后,我们将构建一个具备以下功能的 Ionic 应用:
- 允许用户登录其 Authany 项目下的账号
- 允许新用户注册
- 允许已登录用户查看用户信息并登出
我们将要构建的应用最终界面如下所示:

Authany Ionic 示例应用首页
Prerequisites¶
为顺利完成本指南,请确保已具备以下条件:
- 本地机器上已安装 Node.js
- Android Studio(用于构建应用的 Android 客户端)
- Xcode(用于构建应用的 iOS 客户端)
- 一个 Authany 账号。您可以点击这里免费注册。
- 任意代码编辑器(VS Code、Sublime 等)
按照本指南,只需 🕐 10 分钟即可将 Authany 添加到您的 Ionic 应用中。
Setup Application in Authany Portal¶
在这部分,您将学习如何配置将在 Ionic 项目中使用的 Authany 客户端应用。您需要在 Authany 管理台中完成以下步骤。
Step 1: Set up an Authany Application¶
首先,登录 https://manage.authany.com/ 上的 Authany 管理台,选择一个已有项目或创建一个新项目。
在您的项目中,进入 应用 部分,然后点击 Add Application 创建一个新的 Authany 应用。为应用输入一个名称,并将 Application Type 选择为 Native App。接着点击 Save,进入新应用的配置页面。可以跳过展示不同框架教程列表的页面。

创建新的 Authany 客户端应用
Step 2: Add Authorized Redirect URIs¶
在这一步,您将为应用设置授权重定向 URI。授权重定向 URI 应指向 Ionic 应用中的一个页面,即授权流程结束时希望将用户重定向到的位置。
要添加 URI,请滚动到应用配置页面的 URIs 部分,在文本框中输入 URI。您可以点击 Add URI 按钮添加更多 URI。
在我们的示例应用中,添加以下 URI:
com.authgear.example.capacitor://host/pathcapacitor://localhosthttp://localhost:8100/oauth-redirecthttps://localhost

Authany 应用重定向 URI
完成后,点击 Save 按钮。
Add Authany to an Ionic App¶
现在您已经配置好 Authany 应用,可以开始创建具备前面目标中所述全部功能的 Ionic 应用了。
在本教程中,我们将使用 React 实现一个 Ionic 应用。
Step 1: Create Ionic Project¶
在创建 Ionic 项目之前,请在终端或命令提示符中运行以下命令,在计算机上安装 Ionic CLI:
现在运行以下命令创建一个新的 Ionic 项目:
运行上述命令后,按照向导创建一个新的空白项目(blank project)。
接着,在代码编辑器中打开新项目,将 capacitor.config.ts 中的 appId 更新为以下值:
这个新的 appId 值与我们之前在授权重定向 URI 中使用的值相同。
说明
注意: 请务必在为 Ionic 应用创建 Android 和 iOS 项目之前更新 appId 的值。这样 Capacitor 才能使用该 appId 值作为包名和 App ID 来创建您的 Android 和 iOS 项目。
在新 Ionic 项目的根目录下运行以下命令,即可在浏览器中预览空白项目:
最后,在 Ionic 项目的根目录下运行以下命令,为应用创建 Android 和 iOS 项目:
首先,安装 Android 和 iOS 平台:
然后,创建项目:
Step 2: Install Authany SDK¶
在这一步,您将安装用于 Ionic(Capacitor)的 Authany SDK,以及用于 Web 的 JavaScript SDK。Web SDK 可以帮助您在浏览器中测试应用。
要安装这些 SDK,请在终端或命令提示符中运行以下命令:
Authany Ionic SDK
Authany Web SDK
Step 3: Configure Authany SDK¶
在这一步,您将学习如何使用 Authany 应用配置中的信息来配置 Ionic 项目。
首先,在代码编辑器中打开 src/pages/Home.tsx,在文件顶部添加以下代码以导入 Authany SDK:
import authgearWeb, {
SessionState,
WebContainer,
SessionStateChangeReason,
} from "@authgear/web";
import authgearCapacitor, {
CapacitorContainer,
Page,
} from "@authgear/capacitor";
上面的代码导入了示例应用所需的全部 Authany SDK 组件。
由于 Ionic 应用既可以在 Web 上运行,也可以在原生移动平台上运行,因此我们需要同时导入 Authany Web SDK 和 Authany Capacitor SDK。
接着,在 Home.tsx 最后一条 import 语句下方添加以下常量:
const CLIENT_ID = "<ClIENT_ID>";
const ENDPOINT = "<AUTHGEAR_ENDPOINT>";
const REDIRECT_URI_WEB_AUTHENTICATE = "http://localhost:8100/oauth-redirect";
const REDIRECT_URI_CAPACITOR = "com.authgear.example.capacitor://host/path";
const REDIRECT_URI_WEB_REAUTH = "http://localhost:8100/reauth-redirect";
将常量(CLIENT_ID、ENDPOINT)的值更新为 Authany 管理台中客户端应用配置页面上的正确值。
现在,在常量下方添加这个小工具函数,用于判断 Ionic 应用是运行在原生环境还是浏览器中:
在 Home.tsx 顶部的 import 部分添加以下内容以导入 Capacitor:
您将使用上面的函数,根据用户当前所在的平台来决定调用哪个 Authany SDK 实例。
现在,将以下代码粘贴到 Home.tsx 中,实现一个新的 AuthenticationScreen 组件:
function AuthenticationScreen() {
const [sessionState, setSessionState] = useState<SessionState | null>(() => {
if (isPlatformWeb()) {
return authgearWeb.sessionState;
}
return authgearCapacitor.sessionState;
});
const loggedIn = sessionState === "AUTHENTICATED";
const delegate = useMemo(() => {
const d = {
onSessionStateChange: (
container: WebContainer | CapacitorContainer,
_reason: SessionStateChangeReason
) => {
setSessionState(container.sessionState);
},
};
return d;
}, [setSessionState]);
useEffect(() => {
if (isPlatformWeb()) {
authgearWeb.delegate = delegate;
} else {
authgearCapacitor.delegate = delegate;
}
return () => {
if (isPlatformWeb()) {
authgearWeb.delegate = undefined;
} else {
authgearCapacitor.delegate = undefined;
}
};
}, [delegate]);
return (
<>
<div className="container">
</div>
</>
);
}
在 Home.tsx 顶部导入 useState、useMemo、useEffect 和 useCallback:
上面的代码还实现了一个 sessionState 常量,以及一个用于在用户会话状态发生变化时通知应用的委托。
接着,在 AuthenticationScreen 组件的 return 语句之前,添加以下 configure() 方法:
const configure = useCallback(async () => {
try {
if (isPlatformWeb()) {
await authgearWeb.configure({
clientID: CLIENT_ID,
endpoint: ENDPOINT,
sessionType: "refresh_token",
isSSOEnabled: false,
});
} else {
await authgearCapacitor.configure({
clientID: CLIENT_ID,
endpoint: ENDPOINT,
});
}
await postConfigure();
} catch (e) {
console.error("Authgear Configuration error:", e);
}
}, [CLIENT_ID, ENDPOINT]);
上面的代码使用我们在本指南第一部分创建的 Authany 客户端应用的 Client ID 和 Endpoint,配置了一个新的 Authany SDK 实例。
接着,实现在 configure() 方法中调用的 postConfigure() 方法:
const postConfigure = useCallback(async () => {
const sessionState = isPlatformWeb()
? authgearWeb.sessionState
: authgearCapacitor.sessionState;
// if user has an existing session, call SDK fetchUserInfo method to get the user's info and refresh access token when necessary
if (sessionState === "AUTHENTICATED") {
if (isPlatformWeb()) {
await authgearWeb.fetchUserInfo();
} else {
await authgearCapacitor.fetchUserInfo();
}
}
}, []);
postConfigure() 方法会检查用户是否已通过身份验证,并调用 Authany SDK 的 fetchUserInfo() 方法。调用 fetchUserInfo() 方法会在用户的访问令牌过期时将其刷新。
现在,在 postConfigure() 方法之后添加以下代码,在 useEffect 中调用 configure() 方法:
上面的 useEffect 会在页面加载时初始化 Authany。
Step 4: Add Login Button¶
在这一步,我们将添加登录按钮,以及要展示给已通过身份验证用户的 UI 组件。
在 AuthenticationScreen 组件 return 语句中的 <div> 内添加以下代码:
<h1>
Welcome
</h1>
{!loggedIn ? (
<IonButton
className="button"
// disabled={!initialized || loading || loggedIn}
onClick={
(event) => {
onClickAuthenticate(event, "login")
}
}
>
Login
</IonButton>
):
(
<div>
<p>Welcome user</p>
</div>
)}
将 IonButton 添加到应用中其他 Ionic 组件的 import 语句中:
最后,将 <AuthenticationScreen/> 组件添加到 Home 组件中:
const Home: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Blank</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Blank</IonTitle>
</IonToolbar>
</IonHeader>
<AuthenticationScreen />
</IonContent>
</IonPage>
);
};
Step 5: Start Authentication¶
在这一步,我们将在上一步创建的 AuthenticationScreen 组件内实现一个 authenticate() 方法。
为此,首先在 AuthenticationScreen() 组件的 return 语句之前添加以下代码:
const authenticate = useCallback(async (page: string) => {
try {
if (isPlatformWeb()) {
authgearWeb.startAuthentication({
redirectURI: REDIRECT_URI_WEB_AUTHENTICATE,
page: page,
});
} else {
const result = await authgearCapacitor.authenticate({
redirectURI: REDIRECT_URI_CAPACITOR,
page: page,
});
}
} catch (e) {
console.error("Authentication error:", e);
}
}, []);
调用这个 authenticate() 方法会启动身份验证流程。page 参数可用于指定在 login 页面还是 signup 页面启动身份验证流程。
最后,实现一个 onClickAuthenticate() 方法,在按下登录按钮时调用 authenticate:
const onClickAuthenticate = useCallback(
(e: MouseEvent<HTMLIonButtonElement>, page: string) => {
e.preventDefault();
e.stopPropagation();
authenticate(page);
},
[authenticate]
);
导入 MouseEvent:
Checkpoint¶
至此,Home.tsx 的完整代码应如下所示:
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonButton,
} from "@ionic/react";
import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Capacitor } from "@capacitor/core";
import type { MouseEvent } from "react";
import authgearWeb, {
SessionState,
WebContainer,
SessionStateChangeReason,
} from "@authgear/web";
import authgearCapacitor, {
CapacitorContainer,
Page,
} from "@authgear/capacitor";
import "./Home.css";
const CLIENT_ID = <ClIENT_ID>";
const ENDPOINT = "<AUTHGEAR_ENDPOINT>";
const REDIRECT_URI_WEB_AUTHENTICATE = "http://localhost:8100/oauth-redirect";
const REDIRECT_URI_CAPACITOR = "com.authgear.example.capacitor://host/path";
function isPlatformWeb(): boolean {
return Capacitor.getPlatform() === "web";
}
function AuthenticationScreen() {
const [sessionState, setSessionState] = useState<SessionState | null>(() => {
if (isPlatformWeb()) {
return authgearWeb.sessionState;
}
return authgearCapacitor.sessionState;
});
const loggedIn = sessionState === "AUTHENTICATED";
const delegate = useMemo(() => {
const d = {
onSessionStateChange: (
container: WebContainer | CapacitorContainer,
_reason: SessionStateChangeReason
) => {
setSessionState(container.sessionState);
},
};
return d;
}, [setSessionState]);
useEffect(() => {
if (isPlatformWeb()) {
authgearWeb.delegate = delegate;
} else {
authgearCapacitor.delegate = delegate;
}
return () => {
if (isPlatformWeb()) {
authgearWeb.delegate = undefined;
} else {
authgearCapacitor.delegate = undefined;
}
};
}, [delegate]);
const configure = useCallback(async () => {
try {
if (isPlatformWeb()) {
await authgearWeb.configure({
clientID: CLIENT_ID,
endpoint: ENDPOINT,
sessionType: "refresh_token",
isSSOEnabled: false,
});
} else {
await authgearCapacitor.configure({
clientID: CLIENT_ID,
endpoint: ENDPOINT,
});
}
await postConfigure();
} catch (e) {
console.error("Authgear Configuration error:", e);
}
}, [CLIENT_ID, ENDPOINT]);
const postConfigure = useCallback(async () => {
const sessionState = isPlatformWeb()
? authgearWeb.sessionState
: authgearCapacitor.sessionState;
// if user has an existing session, call SDK fetchUserInfo method to get the user's info and refresh access token when necessary
if (sessionState === "AUTHENTICATED") {
if (isPlatformWeb()) {
await authgearWeb.fetchUserInfo();
} else {
await authgearCapacitor.fetchUserInfo();
}
}
}, []);
useEffect(() => {
configure();
}, []);
const authenticate = useCallback(async (page: string) => {
try {
if (isPlatformWeb()) {
authgearWeb.startAuthentication({
redirectURI: REDIRECT_URI_WEB_AUTHENTICATE,
page: page,
});
} else {
const result = await authgearCapacitor.authenticate({
redirectURI: REDIRECT_URI_CAPACITOR,
page: page,
});
}
} catch (e) {
console.error("Authentication error:", e);
}
}, []);
const onClickAuthenticate = useCallback(
(e: MouseEvent<HTMLIonButtonElement>, page: string) => {
e.preventDefault();
e.stopPropagation();
authenticate(page);
},
[authenticate]
);
return (
<>
<div className="container">
<h1>Welcome</h1>
{!loggedIn ? (
<IonButton
className="button"
onClick={(event) => {
onClickAuthenticate(event, "login");
}}
>
Login
</IonButton>
) : (
<div>
<p>Welcome user</p>
</div>
)}
</div>
</>
);
}
const Home: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Blank</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">Blank</IonTitle>
</IonToolbar>
</IonHeader>
<AuthenticationScreen />
</IonContent>
</IonPage>
);
};
export default Home;
保存好您的工作,然后运行命令在 Web 上运行项目,或将其构建为 iOS 或 Android 应用。
点击登录按钮后,您应该能看到身份验证界面。不过,由于我们还没有处理重定向,此时还无法完成身份验证流程。
Step 6: Handle Redirect in App¶
身份验证流程结束时,用户会被重定向到您在 redirectURI 中指定的 URL。在这一步,我们将设置处理这些重定向 URI 所需的路由和代码。
要在 Web 上处理重定向,请在 src/pages/ 下新建文件 OAuthRedirect.tsx,并添加以下代码:
import { useCallback, useEffect } from "react";
import authgearWeb from "@authgear/web";
import { useIonRouter } from "@ionic/react";
export default function OAuthRedirect() {
const router = useIonRouter();
const finishAuthentication = useCallback(async () => {
const CLIENT_ID = "<ClIENT_ID>";
const ENDPOINT = "<AUTHGEAR_ENDPOINT>";
try {
await authgearWeb.configure({
clientID: CLIENT_ID,
endpoint: ENDPOINT,
sessionType: "refresh_token",
});
await authgearWeb.finishAuthentication();
router.push("/", "root", "replace");
} catch (e) {
console.error(e);
}
}, [router]);
useEffect(() => {
finishAuthentication();
}, [finishAuthentication]);
return (
<div>
Finishing authentication. Open the inspector to see if there is any error.
</div>
);
}
将上面代码中 CLIENT_ID 和 ENDPOINT 的值改为您 Authany 应用配置页面中的正确值。
现在打开 src/App.tsx,使用以下代码为 OAuthRedirect 创建一个新路由:
记得在 App.tsx 中导入 OAuthRedirect:
要在 Android 项目中处理重定向,请将以下代码添加到 android/app/src/main/AndroidManifest.xml 中:
<!-- Authgear SDK -->
<activity
android:name="com.authgear.capacitor.OAuthRedirectActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Configure data to be the exact redirect URI your app uses. -->
<!-- NOTE: The redirectURI supplied in AuthenticateOptions has to match as well -->
<data
android:host="host"
android:pathPrefix="/path"
android:scheme="com.authgear.example.capacitor" />
</intent-filter>
</activity>
至此,构建并运行项目后,您应该可以成功登录。
Step 7: Implement Logout¶
要实现登出功能,我们将添加一个登出按钮、一个 onClick 处理函数,以及一个调用 Authany SDK 的 logout() 方法的方法。
在 AuthenticationScreen 组件中 <p>Welcome user</p> 下方添加一个登出按钮:
接着,为 AuthenticationScreen 组件添加一个 logout() 方法:
const logout = useCallback(async () => {
try {
if (isPlatformWeb()) {
await authgearWeb.logout({
redirectURI: window.location.origin + "/",
});
} else {
await authgearCapacitor.logout();
}
} catch (e) {
console.error("Logout error:", e);
}
}, []);
最后,在 AuthenticationScreen 中实现 onClick 方法:
const onClickLogout = useCallback(
(e: MouseEvent<HTMLIonButtonElement>) => {
e.preventDefault();
e.stopPropagation();
logout();
},
[logout]
);
Step 8: Get UserInfo¶
Authany SDK 提供了一个 fetchUserInfo() 方法,可以返回当前用户的 User ID、邮箱、手机号等信息。在这一步,我们将演示如何在应用中调用 fetchUserInfo。
首先,在 AuthenticationScreen 组件中登出按钮下方添加一个 Fetch User Info 按钮:
接着,为 AuthenticationScreen 组件添加一个 fetchUserInfo() 方法:
const fetchUserInfo = useCallback(async () => {
try {
const authgear = isPlatformWeb() ? authgearWeb : authgearCapacitor;
const userInfo = await authgear.fetchUserInfo();
alert(JSON.stringify(userInfo, null, 2)); // Keep for demonstration, but consider a better way to display info
} catch (e) {
console.error("FetchUserInfo error:", e);
}
}, []);
最后,添加处理 Fetch User Info 按钮点击事件的方法:
const onClickFetchUserInfo = useCallback(
(e: MouseEvent<HTMLIonButtonElement>) => {
e.preventDefault();
e.stopPropagation();
fetchUserInfo();
},
[fetchUserInfo]
);
Step 9: Open User Settings Screen¶
Authany 提供了一个默认的用户设置页面,用户可以在其中查看资料详情,并修改密码等安全设置。
为了让用户可以从应用中打开设置页面,首先在 AuthenticationScreen 组件中 Fetch User Info 按钮下方添加一个 User Settings 按钮:
现在,在 AuthenticationScreen 组件中添加一个 openUserSettings() 方法:
const openUserSettings = useCallback(async () => {
try {
if (isPlatformWeb()) {
authgearWeb.open(Page.Settings);
} else {
authgearCapacitor.open(Page.Settings);
}
} catch (e) {
console.error("Error:", e)
}
}, []);
最后,为 User Settings 按钮实现 onClick 方法:
const onClickUserSettings = useCallback(
(e: MouseEvent<HTMLIonButtonElement>) => {
e.preventDefault();
e.stopPropagation();
openUserSettings();
},
[logout]
);
Step 10: Deploy app to mobile¶
要将应用部署到移动设备(例如 Android),请运行以下命令:
首先运行以下命令构建项目:
然后使用以下命令将更改同步到移动端项目:
您可以在 Android Studio 中打开 android 项目文件夹,或在 Xcode 中打开 ios 文件夹来运行项目。
您可以使用以下命令快速在 Android Studio 中打开项目:
或者运行以下命令,在 Xcode 中打开 iOS 项目:
项目成功构建后,您就可以试用登录、注册、Fetch User Info 和登出按钮了。
Conclusion¶
Authany Capacitor SDK 让您在 Ionic 应用中使用 Authany 变得更加轻松,提供了许多便捷的方法和接口,方便 Ionic 应用与 Authany 服务交互。要了解更多关于该 SDK 的信息,请查看 SDK 参考文档。另外,您也可以查看 Authany Ionic SDK 示例应用的完整仓库。